질문자 :Ian Boyd
당신은 어떻게 열거 할 수 enum
C #에서를?
예를 들어 다음 코드는 컴파일되지 않습니다.
public enum Suit { Spades, Hearts, Clubs, Diamonds } public void EnumerateAllSuitsDemoMethod() { foreach (Suit suit in Suit) { DoSomething(suit); } }
그리고 다음과 같은 컴파일 타임 오류가 발생합니다.
'슈트'는 '유형'이지만 '변수'처럼 사용됩니다.
두 번째 키워드인 Suit
키워드에서는 실패합니다.
답변자 : jop
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit))) { }
참고 (Suit[])
로의 캐스트는 꼭 필요한 것은 아니지만 코드를 0.5ns 더 빠르게 만듭니다.
답변자 : Haacked
값이 아닌 각 열거형의 이름을 인쇄하려는 것처럼 보입니다. 이 경우 Enum.GetNames()
가 올바른 접근 방식인 것 같습니다.
public enum Suits { Spades, Hearts, Clubs, Diamonds, NumSuits } public void PrintAllSuits() { foreach (string name in Enum.GetNames(typeof(Suits))) { System.Console.WriteLine(name); } }
그건 그렇고, 값을 증가시키는 것은 열거형의 값을 열거하는 좋은 방법이 아닙니다. 대신 이 작업을 수행해야 합니다.
Enum.GetValues(typeof(Suit))
사용합니다.
public enum Suits { Spades, Hearts, Clubs, Diamonds, NumSuits } public void PrintAllSuits() { foreach (var suit in Enum.GetValues(typeof(Suits))) { System.Console.WriteLine(suit.ToString()); } }
답변자 : bob
열거형을 쉽게 사용할 수 있도록 몇 가지 확장을 만들었습니다. 누군가가 사용할 수 있을지도...
public static class EnumExtensions { /// <summary> /// Gets all items for an enum value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The value.</param> /// <returns></returns> public static IEnumerable<T> GetAllItems<T>(this Enum value) { foreach (object item in Enum.GetValues(typeof(T))) { yield return (T)item; } } /// <summary> /// Gets all items for an enum type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The value.</param> /// <returns></returns> public static IEnumerable<T> GetAllItems<T>() where T : struct { foreach (object item in Enum.GetValues(typeof(T))) { yield return (T)item; } } /// <summary> /// Gets all combined items from an enum value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The value.</param> /// <returns></returns> /// <example> /// Displays ValueA and ValueB. /// <code> /// EnumExample dummy = EnumExample.Combi; /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>()) /// { /// Console.WriteLine(item); /// } /// </code> /// </example> public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value) { int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture); foreach (object item in Enum.GetValues(typeof(T))) { int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture); if (itemAsInt == (valueAsInt & itemAsInt)) { yield return (T)item; } } } /// <summary> /// Determines whether the enum value contains a specific value. /// </summary> /// <param name="value">The value.</param> /// <param name="request">The request.</param> /// <returns> /// <c>true</c> if value contains the specified value; otherwise, <c>false</c>. /// </returns> /// <example> /// <code> /// EnumExample dummy = EnumExample.Combi; /// if (dummy.Contains<EnumExample>(EnumExample.ValueA)) /// { /// Console.WriteLine("dummy contains EnumExample.ValueA"); /// } /// </code> /// </example> public static bool Contains<T>(this Enum value, T request) { int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture); int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture); if (requestAsInt == (valueAsInt & requestAsInt)) { return true; } return false; } }
열거형 자체는 FlagsAttribute 로 장식되어야 합니다.
[Flags] public enum EnumExample { ValueA = 1, ValueB = 2, ValueC = 4, ValueD = 8, Combi = ValueA | ValueB }
답변자 : Ekevoo
.NET 프레임워크의 일부 버전은 Enum.GetValues
지원하지 않습니다. 다음은 Ideas 2.0의 좋은 해결 방법입니다 . Enum.GetValues in Compact Framework :
public Enum[] GetValues(Enum enumeration) { FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public); Enum[] enumerations = new Enum[fields.Length]; for (var i = 0; i < fields.Length; i++) enumerations[i] = (Enum) fields[i].GetValue(enumeration); return enumerations; }
리플렉션 이 포함된 모든 코드와 마찬가지로 한 번만 실행되고 결과가 캐시되도록 조치를 취해야 합니다.
답변자 : sircodesalot
Cast<T>
:
var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();
IEnumerable<Suit>
입니다.
답변자 : James
루프가 있을 때마다 GetValues()
가 호출되지 않기 때문에 이것이 다른 제안보다 더 효율적이라고 생각합니다. 또한 더 간결합니다. Suit
enum
이 아닌 경우 런타임 예외가 아닌 컴파일 타임 오류가 발생합니다.
EnumLoop<Suit>.ForEach((suit) => { DoSomethingWith(suit); });
EnumLoop
에는 다음과 같은 완전히 일반적인 정의가 있습니다.
class EnumLoop<Key> where Key : struct, IConvertible { static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key)); static internal void ForEach(Action<Key> act) { for (int i = 0; i < arr.Length; i++) { act(arr[i]); } } }
답변자 : Aubrey Taylor
Silverlight 에서는 Enum.GetValues()
를 얻을 수 없습니다.
Einar Ingebrigtsen의 블로그 원본 :
public class EnumHelper { public static T[] GetValues<T>() { Type enumType = typeof(T); if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); } List<T> values = new List<T>(); var fields = from field in enumType.GetFields() where field.IsLiteral select field; foreach (FieldInfo field in fields) { object value = field.GetValue(enumType); values.Add((T)value); } return values.ToArray(); } public static object[] GetValues(Type enumType) { if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); } List<object> values = new List<object>(); var fields = from field in enumType.GetFields() where field.IsLiteral select field; foreach (FieldInfo field in fields) { object value = field.GetValue(enumType); values.Add(value); } return values.ToArray(); } }
답변자 : Mallox
내 솔루션은 .NET Compact Framework (3.5) 에서 작동하며 컴파일 시 유형 검사를 지원합니다.
public static List<T> GetEnumValues<T>() where T : new() { T valueType = new T(); return typeof(T).GetFields() .Select(fieldInfo => (T)fieldInfo.GetValue(valueType)) .Distinct() .ToList(); } public static List<String> GetEnumNames<T>() { return typeof (T).GetFields() .Select(info => info.Name) .Distinct() .ToList(); }
-
T valueType = new T()
제거하는 방법을 알고 있다면 솔루션을 보게 되어 기쁩니다.
호출은 다음과 같습니다.
List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
답변자 : Tom Carr
나는 당신이 사용할 수 있다고 생각합니다
Enum.GetNames(Suit)
답변자 : Joshua Drake
public void PrintAllSuits() { foreach(string suit in Enum.GetNames(typeof(Suits))) { Console.WriteLine(suit); } }
답변자 : lmat - Reinstate Monica
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
나는 이것이 엄청나게 느리다는 막연한 소문을 들었습니다. 아는 사람? – Orion Edwards 2008년 10월 15일 1:31 7
어레이를 캐싱하면 속도가 상당히 빨라질 것이라고 생각합니다. 매번 (반사를 통해) 새로운 배열을 얻는 것처럼 보입니다. 꽤:
Array enums = Enum.GetValues(typeof(Suit)); foreach (Suit suitEnum in enums) { DoSomething(suitEnum); }
최소한 조금 더 빠르겠죠?
답변자 : Darkside
최고의 답변을 결합하여 매우 간단한 확장을 만들었습니다.
public static class EnumExtensions { /// <summary> /// Gets all items for an enum value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The value.</param> /// <returns></returns> public static IEnumerable<T> GetAllItems<T>(this T value) where T : Enum { return (T[])Enum.GetValues(typeof (T)); } }
깨끗하고 간단하며 @Jeppe-Stig-Nielsen의 의견에 따르면 빠릅니다.
답변자 : nawfal
세 가지 방법:
-
Enum.GetValues(type)
// .NET 1.1 이후, Silverlight 또는 .NET Compact Framework에는 없음 -
type.GetEnumValues()
// .NET 4 이상에서만 -
type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// 어디서나 작동
GetEnumValues
가 유형 인스턴스에 도입된 이유를 잘 모르겠습니다. 그것은 나를 위해 전혀 읽을 수 없습니다.
Enum<T>
와 같은 도우미 클래스를 갖는 것이 가장 읽기 쉽고 기억에 남습니다.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible { public static IEnumerable<T> GetValues() { return (T[])Enum.GetValues(typeof(T)); } public static IEnumerable<string> GetNames() { return Enum.GetNames(typeof(T)); } }
이제 전화를 겁니다.
Enum<Suit>.GetValues(); // Or Enum.GetValues(typeof(Suit)); // Pretty consistent style
성능이 중요한 경우 일종의 캐싱을 사용할 수도 있지만 이것이 문제가 될 것이라고는 생각하지 않습니다.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible { // Lazily loaded static T[] values; static string[] names; public static IEnumerable<T> GetValues() { return values ?? (values = (T[])Enum.GetValues(typeof(T))); } public static IEnumerable<string> GetNames() { return names ?? (names = Enum.GetNames(typeof(T))); } }
답변자 : Kylo Ren
Enum
을 반복하는 두 가지 방법이 있습니다.
1. var values = Enum.GetValues(typeof(myenum)) 2. var values = Enum.GetNames(typeof(myenum))
첫 번째는 ** object
**s의 배열 형식으로 값을 제공하고 두 번째는 ** String
**s의 배열 형식으로 값을 제공합니다.
아래와 같이 foreach
루프에서 사용합니다.
foreach(var value in values) { // Do operations here }
답변자 : Mickey Perlstein
ToString()을 사용한 다음 플래그에서 spit 배열을 분할하고 구문 분석합니다.
[Flags] public enum ABC { a = 1, b = 2, c = 4 }; public IEnumerable<ABC> Getselected (ABC flags) { var values = flags.ToString().Split(','); var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim())); return enums; } ABC temp= ABC.a | ABC.b; var list = getSelected (temp); foreach (var item in list) { Console.WriteLine(item.ToString() + " ID=" + (int)item); }
답변자 : Arad
새로운 .NET 5 솔루션:
.NET 5는 GetValues
메서드에 대한 일반 버전을 도입했습니다.
Suit[] suitValues = Enum.GetValues<Suit>();
foreach 루프에서의 사용법:
foreach (Suit suit in Enum.GetValues<Suit>()) { }
지금까지 가장 편리한 솔루션입니다.
그리고 열거형 이름을 얻으려면:
string[] suitNames = Enum.GetNames<Suit>();
답변자 : nawfal
나는 이것이 더 좋거나 심지어 좋다는 의견을 가지고 있지 않습니다. 나는 또 다른 해결책을 말할 뿐입니다.
열거형 값의 범위가 엄격하게 0에서 n - 1인 경우 일반적인 대안은 다음과 같습니다.
public void EnumerateEnum<T>() { int length = Enum.GetValues(typeof(T)).Length; for (var i = 0; i < length; i++) { var @enum = (T)(object)i; } }
열거형 값이 연속적이고 열거형의 첫 번째 요소와 마지막 요소를 제공할 수 있는 경우 다음을 수행합니다.
public void EnumerateEnum() { for (var i = Suit.Spade; i <= Suit.Diamond; i++) { var @enum = i; } }
그러나 그것은 엄밀히 열거하는 것이 아니라 그냥 반복하는 것입니다. 두 번째 방법은 다른 방법보다 훨씬 빠르지만...
답변자 : dmihailescu
빌드 및 런타임 시 속도 및 유형 검사가 필요한 경우 LINQ를 사용하여 각 요소를 캐스팅하는 것보다 이 도우미 메서드가 더 좋습니다.
public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible { if (typeof(T).BaseType != typeof(Enum)) { throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T))); } return Enum.GetValues(typeof(T)) as T[]; }
그리고 아래와 같이 사용할 수 있습니다.
static readonly YourEnum[] _values = GetEnumValues<YourEnum>();
IEnumerable<T>
반환할 수 있지만 여기서는 아무 것도 사지 않습니다.
답변자 : jhilden
다음은 DDL에 대한 선택 옵션을 만드는 작업 예입니다.
var resman = ViewModelResources.TimeFrame.ResourceManager; ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame in Enum.GetValues(typeof(MapOverlayTimeFrames)) select new SelectListItem { Value = timeFrame.ToString(), Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString() };
답변자 : matt burns
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
(현재 허용되는 답변에는 필요하지 않다고 생각되는 캐스트가 있습니다(틀릴 수 있지만).)
답변자 : anar khalilov
나는 그것이 약간 지저분하다는 것을 알고 있지만 한 줄짜리 팬이라면 여기 하나가 있습니다.
((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
답변자 : MUT
다음과 같이 public static IEnumerable<T> GetValues<T>()
를 클래스에 추가합니다.
public static IEnumerable<T> GetValues<T>() { return Enum.GetValues(typeof(T)).Cast<T>(); }
열거 형을 호출하고 전달하십시오. foreach
사용하여 반복할 수 있습니다.
public static void EnumerateAllSuitsDemoMethod() { // Custom method var foos = GetValues<Suit>(); foreach (var foo in foos) { // Do something } }
답변자 : Ross Gatih
이 질문은 "C# Step by Step 2013 "의 10장에 나와 있습니다.
작성자는 이중 for 루프를 사용하여 한 쌍의 Enumerator를 반복합니다(전체 카드 데크 만들기).
class Pack { public const int NumSuits = 4; public const int CardsPerSuit = 13; private PlayingCard[,] cardPack; public Pack() { this.cardPack = new PlayingCard[NumSuits, CardsPerSuit]; for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++) { for (Value value = Value.Two; value <= Value.Ace; value++) { cardPack[(int)suit, (int)value] = new PlayingCard(suit, value); } } } }
이 경우 Suit
와 Value
는 모두 열거형입니다.
enum Suit { Clubs, Diamonds, Hearts, Spades } enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}
PlayingCard
Suit
및 Value
가 있는 카드 개체입니다.
class PlayingCard { private readonly Suit suit; private readonly Value value; public PlayingCard(Suit s, Value v) { this.suit = s; this.value = v; } }
답변자 : Gabriel
열거형을 상호 작용할 수 있는 것으로 변환하는 간단하고 일반적인 방법:
public static Dictionary<int, string> ToList<T>() where T : struct { return ((IEnumerable<T>)Enum .GetValues(typeof(T))) .ToDictionary( item => Convert.ToInt32(item), item => item.ToString()); }
그리고:
var enums = EnumHelper.ToList<MyEnum>();
답변자 : Slappywag
유형이 enum
것을 알고 있지만 컴파일 타임에 정확한 유형이 무엇인지 모른다면 어떻게 될까요?
public class EnumHelper { public static IEnumerable<T> GetValues<T>() { return Enum.GetValues(typeof(T)).Cast<T>(); } public static IEnumerable getListOfEnum(Type type) { MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type); return (IEnumerable)getValuesMethod.Invoke(null, null); } }
getListOfEnum
메서드는 리플렉션을 사용하여 열거형 유형을 취하고 모든 열거형 값 IEnumerable
용법:
Type myType = someEnumValue.GetType(); IEnumerable resultEnumerable = getListOfEnum(myType); foreach (var item in resultEnumerable) { Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item)); }
답변자 : Emily Chen
enum
형은 값을 "열거"하는 컨테이너이기 때문에가 아니라 해당 유형의 변수에 대한 가능한 값을 열거하여 정의되기 때문에 "열거형 유형"이라고 합니다.
(사실, 그것은 그것보다 조금 더 복잡합니다. 열거형 유형은 "기본" 정수 유형을 갖는 것으로 간주됩니다. 이는 각 열거형 값이 정수 값에 해당함을 의미합니다(일반적으로 암시적이지만 수동으로 지정할 수 있음). C#이 설계되었습니다. 당신이이 "라는"값없는 경우에도, 열거 변수에 해당 유형의 정수를 채울 수 있도록하는 방법이다.)
System.Enum.GetNames 메서드 는 이름에서 알 수 있듯이 열거형 값의 이름인 문자열 배열을 검색하는 데 사용할 수 있습니다.
편집: 대신 System.Enum.GetValues 메서드를 제안해야 합니다. 죄송합니다.
답변자 : reza akhlaghi
열거형에서 int 목록을 얻으려면 다음을 사용하십시오. 효과가있다!
List<int> listEnumValues = new List<int>(); YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType)); foreach ( YourEnumType enumMember in myEnumMembers) { listEnumValues.Add(enumMember.GetHashCode()); }
답변자 : Termininja
또한 리플렉션을 사용하여 열거형의 공용 정적 멤버에 직접 바인딩할 수도 있습니다.
typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static) .ToList().ForEach(x => DoSomething(x.Name));
답변자 : rlv-dan
당신이 가지고 있다면:
enum Suit { Spades, Hearts, Clubs, Diamonds }
이것:
foreach (var e in Enum.GetValues(typeof(Suit))) { Console.WriteLine(e.ToString() + " = " + (int)e); }
출력합니다:
Spades = 0 Hearts = 1 Clubs = 2 Diamonds = 3
답변자 : marsh-wiggle
이와 같이 약간의 열거 형이있을 때
enum DemoFlags { DemoFlag = 1, OtherFlag = 2, TestFlag = 4, LastFlag = 8, }
이 과제로
DemoFlags demoFlags = DemoFlags.DemoFlag | DemoFlags.TestFlag;
다음과 같은 결과가 필요합니다.
"DemoFlag | TestFlag"
이 방법은 다음을 도와줍니다.
public static string ConvertToEnumString<T>(T enumToConvert, string separator = " | ") where T : Enum { StringBuilder convertedEnums = new StringBuilder(); foreach (T enumValue in Enum.GetValues(typeof(T))) { if (enumToConvert.HasFlag(enumValue)) convertedEnums.Append($"{ enumValue }{separator}"); } if (convertedEnums.Length > 0) convertedEnums.Length -= separator.Length; return convertedEnums.ToString(); }
출처 : Here
출처 : http:www.stackoverflow.com/questions/105372/how-to-enumerate-an-enum">