etc./StackOverFlow

열거형을 열거하는 방법

청렴결백한 만능 재주꾼 2021. 9. 26. 10:52
반응형

질문자 :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


세 가지 방법:

  1. Enum.GetValues(type) // .NET 1.1 이후, Silverlight 또는 .NET Compact Framework에는 없음
  2. type.GetEnumValues() // .NET 4 이상에서만
  3. 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); } } } }

이 경우 SuitValue 는 모두 열거형입니다.

 enum Suit { Clubs, Diamonds, Hearts, Spades } enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

PlayingCard SuitValue 가 있는 카드 개체입니다.

 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">

반응형