열거 형을 열거하는 방법


3765

enumC #에서 어떻게 열거 할 수 있습니까?

예를 들어 다음 코드는 컴파일되지 않습니다.

public enum Suit
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod()
{
    foreach (Suit suit in Suit)
    {
        DoSomething(suit);
    }
}

그리고 다음과 같은 컴파일 타임 오류가 발생합니다.

'정장'은 '유형'이지만 '변수'처럼 사용됩니다.

Suit두 번째 키워드 인 키워드에서는 실패합니다 .



2
C # enums의 내용 을 살펴보고 싶을 수도 있습니다.이 내용 기타 유용한 열거 형 정보
ChaseMedallion

답변:


4613
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

참고 : 캐스트 (Suit[])는 반드시 필요한 것은 아니지만 코드를 0.5ns 더 빠르게 만듭니다.


97
열거 자 목록에 중복 값이 ​​있으면 작동하지 않습니다.
Jessy

10
Silverlight 라이브러리가를 포함하지 않기 때문에 불행히도 silverlight에서 작동하지 않는다는 것을 지적하고 싶습니다 enum.GetValues. 이 경우 리플렉션을 사용해야합니다.
Giacomo Tagliabue

146
이 @Jessy 않습니다 같은 중복 된 상황의 경우에는 일을 enum E {A = 0, B = 0}. Enum.GetValues두 값이 동일하지만 두 값이 반환됩니다. E.A == E.B사실이므로 구별이 없습니다. 개별 이름을 원하면을 찾아야합니다 Enum.GetNames.
nawfal

13
그런 다음 열거 형에 중복 / 동의어가 있고 다른 동작을 원하면 Linq의 Distinct확장명 (.NET 3.5부터)을 사용할 수 있습니다 foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
Jeppe Stig Nielsen

42
var유형 에 사용하려고 실수했습니다 . 컴파일러는 변수를 Object열거 형 대신 변수로 만듭니다 . 열거 형 유형을 명시 적으로 나열하십시오.
jpmc26

695

값이 아닌 각 열거 형의 이름을 실제로 인쇄하려는 것처럼 보입니다. 어떤 경우 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());
    }
}

2
여기 VB 구문 : 링크
AndruWitta

나는 내 옆에서 작은 다음과 같은 변경과 버전을했다 : Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). 이 경우 Suits문자열이 아닌 열거 형 항목의 배열을 반복 할 수 있습니다 .
Barabas 2016 년

@Barabas 왜 안 해 Suits suit in Enum.GetValues(typeof(Suits))?
themadking

@themadking 아! 물론,이 괴물 조각보다 더 정확한 유형의 외모를 사용 쉬 ... 코드!
Barabas

337

쉬운 열거 형 사용을 위해 몇 가지 확장을 만들었습니다. 누군가가 그것을 사용할 수 있습니다 ...

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
}

13
제 1 연장 방법을위한 하나의 라이너; 더 이상 게으르지 않습니다. 반환 Enum.GetValues ​​(typeof (T)). Cast <T> ();
Leyu

2
또는 OfType을 사용할 수도 있습니다 : Enum.GetValues ​​(typeof (T)). OfType <T> (). GetValues ​​<T> ()의 일반 버전이없는 것이 너무 나빠서 훨씬 더 매끄 럽습니다.
jpierson

3
어쩌면 누군가 이러한 확장을 사용하는 방법을 보여줄 수 있습니까? 컴파일러는 열거 형 EnumExample에 확장 메서드를 표시하지 않습니다.
Tomas

1
누구나 그 기능을 사용하는 방법을 예를 추가 할 수 있습니까?
Ashwini Verma

3
재사용 가능한 코드의 경우 +1 : 예제-이러한 확장 메소드를 라이브러리에 저장하고이를 참조하십시오. [Flags] public enum mytypes {name1, name2}; List <string> myTypeNames = mytypes.GetAllItems ();
Krishna

178

.NET 프레임 워크의 일부 버전은 지원하지 않습니다 Enum.GetValues. 다음은 Ideas 2.0 의 좋은 해결 방법 입니다. Compact Framework의 Enum.GetValues :

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;
}

리플렉션 과 관련된 코드와 마찬가지로 코드가 한 번만 실행되고 결과가 캐시되도록 조치를 취해야합니다.


18
리스트를 생성하는 대신 yield 키워드를 사용하지 않는 이유는 무엇입니까?
에릭 미켈슨

1
또는 더 짧은 :return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
nawfal

7
@nawfal : Linq는 .Net CF 2.0을 사용할 수 없습니다.
Gabriel GM

@ Ekevoo이 열거 형 값을 MVC의 DropDownList에 바인딩하는 방법은 무엇입니까?
Jack

115

사용 Cast<T>:

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

당신은 간다 IEnumerable<Suit>.


1
이것은 from절과 foreach헤더 선언자 에서도 작동합니다 .
Aluan Haddad

97

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]);
        }
    }
}

6
이와 같은 제네릭 사용에주의하십시오. EnumLoop열거 형이 아닌 일부 유형 을 사용하려고 하면 컴파일이 잘되지만 런타임에 예외가 발생합니다.
svick

7
svick 감사합니다. 대부분의 경우 컴파일 시간 오류가 발생하도록 "where Key : struct, IConvertible"을 추가했기 때문에이 페이지를 제외한 다른 답변에서 런타임 예외가 실제로 발생합니다.
제임스

3
아니요, GetValues ​​()는 foreach에서 한 번만 호출됩니다.
Alex Blokha

4
제임스, 나는 영리한 것이 기쁘지만 많은 사람들이 유지하고 업데이트 할 생산 코드에서 영리한 것이 추가 작업이기 때문에 수업을 낙담시킬 것입니다. 크게 절약하거나 많이 사용한다면 절약 효과가 커지고 사람들이 익숙해 질 것입니다.하지만 가치가 있지만 대부분의 경우 코드를 읽고 업데이트하려는 사람들의 속도를 늦추고 가능한 가능성을 소개합니다 앞으로 소스 버그. 코드가 적을수록 좋습니다.) 복잡성이 적을수록 좋습니다.
Grant M

2
@GrantM 왜? 이 코드는 복잡하지 않으며 매우 짧습니다. 또한 클래스를 한 번 작성하면 예제를 사용하여 코드를 더 짧게 반복 할 수 있습니다. 이 코드를 업데이트 할 수 없으면 회사 코드를 업데이트 할 수 없습니다.
Dispersia

77

당신은받지 않습니다 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();
    }
}

2
좋은 해결책이지만 일부 리팩토링이 더 좋습니다! :)
nawfal

.NET Framework 4.0 및 silverlight enum.getvalues ​​작업을 사용하고 있는데, 사용한 코드는 ---> enum.GetValues ​​(typeof (enum))
Ananda

2
C # 7.3 (Visual Studio 2017 ≥ v15.7)부터 다음을 사용할 수 있습니다.where T: Enum
Yahoo Serious

59

내 솔루션은 .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>();

2
사용하는 것은 T valueType = default(T)어떻습니까?
Oliver

좋아요, 나는 그 키워드조차 몰랐습니다. 항상 새로운 것을 배우는 것이 좋습니다. 감사합니다! 항상 동일한 객체에 대한 참조를 반환합니까, 아니면 기본 명령문이 호출 될 때마다 새 인스턴스를 작성합니까? 나는 지금까지 그물에서 아무것도 발견하지 못했지만 매번 새로운 인스턴스를 만들면 내가 찾고있는 목적을 잃어 버립니다 (원 라이너가 있음 ^^).
Mallox

1
이것은 열거를 반복 할 때마다 새로운 인스턴스를 생성하지 않습니까?
Mallox

1
"컴파일시 유형 검사 지원 :"에 대해 -1. 어떤 유형 검사? 이것은 어떤 경우에도 작동합니다 new() T. 또한, 당신은 전혀 필요하지 new T()않습니다, 당신은 정적 필드 만 선택하고 할 수 있습니다 .GetValue(null). 오브리의 답변을 참조하십시오.
nawfal

2
C # 7.3 (Visual Studio 2017 ≥ v15.7)부터 다음을 사용할 수 있습니다.where T: Enum
Yahoo Serious

52

나는 당신이 사용할 수 있다고 생각

Enum.GetNames(Suit)

6
Enum.GetValues ​​(Suits)
Ian Boyd

50
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}

2
문자열을 열거하고 열거를 열거 값으로 다시 변환하여 열거를 열거 할 수 있음을 잊지 마십시오.
Ian Boyd

1
편집에서 실제로 열거 형 자체에서 조작하고 싶다는 것을 알았습니다. 위의 코드는 원래 게시물을 처리했습니다.
Joshua Drake

49
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);
}

조금 더 빠릅니다, ja?


5
그러나 컴파일러는이를 처리해야합니다.
Stephan Bijzitter

@StephanBijzitter 와우, 당신은 이것에 대해 아주 많이 읽고 있습니다 :-) 나는 컴파일러가 내 솔루션을 불필요하게 만들어야한다고 동의합니다.
제한적인 속죄

1
필요하지 않습니다. ILSpy에서 컴파일 된 코드를 살펴보면 컴파일러는 이미이 작업을 수행합니다. 왜이 답변이 전혀 35 배나 많이 찬성되지 않습니까?
mhenry1384

1
오래 전에 찬성했습니다. 아주 오래 전에 그래도 컴파일러 가이 문제를 해결했을 것이라고 생각했습니다. 그러나 그것은 확실히 보인다 는 더욱 확대됨하지 않는 이유는 무엇입니까? ;-)
제한적 속죄

32

세 가지 방법 :

  1. Enum.GetValues(type) // Silverlight 또는 .NET Compact Framework가 아닌 .NET 1.1 이후
  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)));
    }
}

이것은 좋은 방법 요약입니다. 그래도 다른 대답을 이것에 병합해야한다고 생각합니다. 진실은 열거 형이 특별하고 그것들을 반복하는 것이 종종 (보통) 열거만큼이나 유효하다는 것입니다. IOW, 항상 변경되는 열거 형이 있으면 잘못된 데이터 구성을 선택했습니다.
krowe2

31

최고의 답변을 결합함으로써 매우 간단한 확장을 함께 던졌습니다.

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의 의견에 따르면 빠릅니다.


6
C # 7.3 (Visual Studio 2017 ≥ v15.7)부터 다음을 사용할 수 있습니다.where T: Enum
Yahoo Serious

24

반복하는 두 가지 방법이 있습니다 Enum.

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

첫 번째는 ** object** 배열에 값을 제공하고 두 번째는 ** String** 배열에 값을 제공합니다 .

foreach아래와 같이 루프 에서 사용하십시오 .

foreach(var value in values)
{
    // Do operations here
}

2
아마도 '이것은 이미 많은 답변으로 덮여 있습니까? 답을 중복하지 말자.
nawfal

@nawfal yes는 다른 답변에서 다루어 질 수 있지만 대부분의 답변은 잘 이루어지지 않았습니다.
Kylo Ren

23

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);
}

17

나는 이것이 더 낫거나 심지어 좋은 것이라는 견해를 가지고 있지 않습니다. 방금 또 다른 해결책을 말하고 있습니다.

열거 형 값의 범위가 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;
    }
}

그러나 그것은 엄격하게 열거되지는 않고 반복됩니다. 두 번째 방법은 다른 접근법보다 훨씬 빠릅니다.


16

빌드 및 런타임시 속도 및 유형 검사가 필요한 경우이 도우미 방법은 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>는 있지만 여기서는 아무것도 사지 않습니다.


3
C # 7.3 (Visual Studio 2017 ≥ v15.7)부터 다음을 사용할 수 있습니다.where T: Enum
Yahoo Serious

14

다음은 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()
      };

10
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(현재 허용되는 답변에는 내가 필요하지 않다고 생각되는 캐스트가 있습니다 (잘못되었을지라도).)


10

이 질문은 " C # Step by Step 2013 "의 10 장에 나타납니다.

저자는 이중 for-loop를 사용하여 한 쌍의 열거자를 반복합니다 (전체 카드 데크 만들기).

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다음 SuitValue같이 정의 된 카드 객체입니다 .

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}

열거 형의 값이 순차적이 아닌 경우 작동합니까?
Aamir Masood 17


8

유형이 인 것을 알고 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));
}

8

열거 형을 상호 작용할 수있는 것으로 변환하는 간단하고 일반적인 방법 :

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>();

A는 Dictionary좋은 생각이 아니다 : 당신이있는 경우 Enum등으로 enum E { A = 0, B = 0 }, 0 값이 생성 2 회 추가 ArgumentException(동일한를 추가 할 수 없습니다 KeyA의 Dictionary2 번 이상!).
Massimiliano Kraus

Dictionary<,>라는 메서드에서 a를 반환 ToList합니까? 또한 왜 돌아 오지 Dictionary<T, string>않습니까?
Aluan Haddad

8

다음 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
     }
 }

2

enum유형은 값을 "열거하는"컨테이너가 아니기 때문에 (열거 형이 아니라) 열거 형 으로 정의되기 때문에 "열거 형"이라고합니다. 해당 유형의 변수에 가능한 값을 하여 입니다.

(실제로, 그것은 그보다 조금 더 복잡합니다-열거 형은 "기본"정수 유형을 갖는 것으로 간주됩니다. 즉, 각 열거 값은 정수 값에 해당합니다 (이는 일반적으로 암시 적이지만 수동으로 지정할 수 있음). 그래서 당신은 물건을 할 수있는 방법 중 하나를 그것이 "라는"값없는 경우에도, 열거 변수에 해당 유형의 정수를.)

System.Enum.GetNames 방법 이름에서 알 수 있듯이, 열거 값들의 이름 문자열의 배열을 검색하기 위해 사용될 수있다.

편집 : 대신 System.Enum.GetValues 메서드를 제안해야 합니다. 죄송합니다.


2
귀하의 답변 자체는 정확하지만 실제로 OP의 원래 질문을 다루지는 않습니다. 이 GetNames메서드는 실제로 문자열 배열을 반환하지만 OP에는 값을 통한 열거자가 필요합니다.
Silviu Preda

@SilviuPreda : 편집했습니다. GetNames 대신 GetValues ​​여야합니다.
Emily Chen

2

나는 여러 가지 방법을 시도 했고이 코드에서 결과를 얻었습니다.

열거 형에서 int 목록을 얻으려면 다음을 사용하십시오. 효과가있다!

List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
    listEnumValues.Add(enumMember.GetHashCode());
}

1
편집에 대한 tanx는 피터 MORTENSEN @
레자 akhlaghi

0

또한 리플렉션을 사용하여 열거 형의 공개 정적 멤버에 직접 바인딩 할 수 있습니다.

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));

0

당신이 가지고 있다면:

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

0

LINQ 일반적인 방법 :

    public static Dictionary<int, string> ToList<T>() where T : struct =>
        ((IEnumerable<T>)Enum.GetValues(typeof(T))).ToDictionary(value => Convert.ToInt32(value), value => value.ToString());

용법:

        var enums = ToList<Enum>();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.