如何在C#中枚举枚举?

时间:2022-10-30 10:46:58

How can you enumerate an enum in C#?

你怎么能枚举C#中的枚举?

E.g. the following code does not compile:

例如。以下代码无法编译:

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

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

And gives the following compile-time error:

并给出以下编译时错误:

'Suit' is a 'type' but is used like a 'variable'

'Suit'是'type',但用作'变量'

It fails on the Suit keyword, the second one.

它在Suit关键字上失败,第二个。

26 个解决方案

#1


3934  

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

#2


573  

It looks to me like you really want to print out the names of each enum, rather than the values. In which case Enum.GetNames() seems to be the right approach.

在我看来,你真的想要打印每个枚举的名称,而不是值。在这种情况下,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);
    }
}

By the way, incrementing the value is not a good way to enumerate the values of an enum. You should do this instead.

顺便说一下,递增值不是枚举枚举值的好方法。你应该这样做。

I would use Enum.GetValues(typeof(Suit)) instead.

我会使用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());
    }
}

#3


288  

I made some extensions for easy enum usage, maybe someone can use it...

我做了一些扩展以便轻松使用枚举,也许有人可以使用它...

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

The enum itself must be decorated with the FlagsAttribute

枚举本身必须使用FlagsAttribute进行修饰

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

#4


148  

Some versions of the .NET framework do not support Enum.GetValues. Here's a good workaround from Ideas 2.0: Enum.GetValues in Compact Framework:

某些版本的.NET框架不支持Enum.GetValues。以下是Ideas 2.0中的一个很好的解决方法:Compact Framework中的Enum.GetValues:

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

As with any code that involves reflection, you should take steps to ensure it runs only once and results are cached.

与涉及反射的任何代码一样,您应该采取措施确保它只运行一次并缓存结果。

#5


85  

I think this is more efficient than other suggestions because GetValues() is not called each time you have a loop. It is also more concise. And you get a compile-time error not a runtime exception if Suit is not an enum.

我认为这比其他建议更有效,因为每次循环时都不会调用GetValues()。它也更简洁。如果Suit不是枚举,则会出现编译时错误,而不是运行时异常。

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop has this completely generic definition:

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


82  

Why is no one using Cast<T>?

为什么没有人使用Cast ?

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

There you go IEnumerable<Suit>.

你去IEnumerable

#7


68  

You won't get Enum.GetValues() in Silverlight.

你不会在Silverlight中获得Enum.GetValues()。

Original Blog Post by Einar Ingebrigtsen:

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

#8


50  

Just to add my solution, which works in compact framework (3.5) and supports type checking at compile time:

只是添加我的解决方案,它在紧凑的框架(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();
}

- If anyone knows how to get rid of the T valueType = new T(), I'd be happy to see a solution.

- 如果有人知道如何摆脱T valueType = new T(),我很乐意看到解决方案。

A call would look like this:

一个电话看起来像这样:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

#9


44  

I think you can use

我想你可以用

Enum.GetNames(Suit)

#10


42  

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

#11


37  

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

I've heard vague rumours that this is terifically slow. Anyone know? – Orion Edwards Oct 15 '08 at 1:31 7

我听到一些含糊不清的谣言说这种情况非常缓慢。谁知道? - 猎户座爱德华兹08年10月15日1:31 7

I think caching the array would speed it up considerably. It looks like you're getting a new array (through reflection) every time. Rather:

我认为缓存阵列会大大加快它的速度。看起来你每次都会得到一个新阵列(通过反射)。而是:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

That's at least a little faster, ja?

这至少要快一点,ja?

#12


21  

Three ways:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

Not sure why was GetEnumValues introduced on type instance, it isn't very readable at all for me.

不确定为什么GetEnumValues在类型实例上引入,它对我来说根本不是很可读。


Having a helper class like Enum<T> is what is most readable and memorable for me:

像Enum 这样的助手类对我来说是最具可读性和难忘性的:

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

Now you call:

现在你打电话:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

One can also use sort of caching if performance matters, but I don't expect this to be an issue at all

如果性能很重要,也可以使用某种缓存,但我不认为这根本就是一个问题

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

#13


20  

What the hell I'll throw my two pence in, just by combining the top answers I through together a very simple extension

我将把我的两便士扔进去,只需将最顶层的答案结合在一起,我就可以通过一个非常简单的扩展

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)
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Clean simple and by @Jeppe-Stig-Nielsen s comment fast.

干净简单,并由@ Jeppe-Stig-Nielsen快速评论。

#14


19  

I use ToString() then split and parse the spit array in flags.

我使用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);
}

#15


19  

There are two ways to iterate an Enum:

迭代枚举有两种方法:

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

The first will give you values in form on a array of object, and the second will give you values in form of array of String.

第一个将在对象数组中为您提供表单中的值,第二个将以String数组的形式为您提供值。

Use it in foreach loop as below:

在foreach循环中使用它如下:

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

#16


13  

I do not hold the opinion this is better, or even good, just stating yet another solution.

If enum values range strictly from 0 to n - 1, a generic alternative:

如果枚举值严格范围从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;
    }
}

If enum values are contiguous and you can provide the first and last element of the enum, then:

如果枚举值是连续的,并且您可以提供枚举的第一个和最后一个元素,那么:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

but that's not strictly enumerating, just looping. The second method is much faster than any other approach though...

但这不是严格的枚举,只是循环。第二种方法比任何其他方法快得多......

#17


13  

If you need speed and type checking at build and run time, this helper method is better than using LINQ to cast each element:

如果在构建和运行时需要速度和类型检查,这个辅助方法比使用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[];
}

And you can use it like below:

你可以像下面这样使用它:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Of course you can return IEnumerable<T>, but that buys you nothing here.

当然你可以返回IEnumerable ,但是这里没有你买的东西。

#18


11  

here is a working example of creating select options for a DDL

这是为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()
      };

#19


9  

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

(The current accepted answer has a cast that I don't think is needed (although I may be wrong).)

(目前接受的答案有一个我认为不需要的演员(尽管我可能错了)。)

#20


8  

This question appears in Chapter 10 of "C# Step by Step 2013"

这个问题出现在“C#Step by Step 2013”​​的第10章中

The author uses a double for-loop to iterate through a pair of Enumerators (to create a full deck of cards):

作者使用双循环来迭代一对枚举器(以创建一副完整的卡片):

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

In this case, Suit and Value are both enumerations:

在这种情况下,Suit和Value都是枚举:

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

and PlayingCard is a card object with a defined Suit and Value:

和PlayingCard是一个具有定义的套装和价值的卡片对象:

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

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

#21


6  

I know it is a bit messy but if you are fan of one-liners, here is one:

我知道它有点乱,但如果你是单行的粉丝,这里有一个:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));

#22


6  

A simple and generic way to convert an enum to something you can interact:

将枚举转换为可以交互的内容的简单通用方法:

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

And then:

var enums = EnumHelper.ToList<MyEnum>();

#23


5  

What if you know the type will be an enum, but you don't know what the exact type is at compile time?

如果您知道类型将是枚举,但您不知道编译时的确切类型是什么?

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

The method getListOfEnum uses reflection to take any enum type and returns an IEnumerable of all enum values.

方法getListOfEnum使用反射来获取任何枚举类型并返回所有枚举值的IEnumerable。

Usage:

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

#24


1  

Add method public static IEnumerable<T> GetValues<T>() to your class, like

添加方法public static IEnumerable GetValues ()到你的类,比如

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

call and pass your enum, now you can iterate through it using foreach

调用并传递你的枚举,现在你可以使用foreach迭代它

 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }

#25


0  

Also you can bind to the public static members of the enum directly by using reflection:

您还可以使用反射直接绑定到枚举的公共静态成员:

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

#26


-1  

enum types are called "enumeration types" not because they are containers that "enumerate" values (which they aren't), but because they are defined by enumerating the possible values for a variable of that type.

枚举类型被称为“枚举类型”,不是因为它们是“枚举”值(它们不是)的容器,而是因为它们是通过枚举该类型变量的可能值来定义的。

(Actually, that's a bit more complicated than that - enum types are considered to have an "underlying" integer type, which means each enum value corresponds to an integer value (this is typically implicit, but can be manually specified). C# was designed in a way so that you could stuff any integer of that type into the enum variable, even if it isn't a "named" value.)

(实际上,这有点复杂 - 枚举类型被认为具有“底层”整数类型,这意味着每个枚举值对应一个整数值(这通常是隐式的,但可以手动指定).C#是设计的在某种程度上,你可以将任何类型的整数填充到枚举变量中,即使它不是“命名”值。)

The System.Enum.GetNames method can be used to retrieve an array of strings which are the names of the enum values, as the name suggests.

System.Enum.GetNames方法可用于检索字符串数组,这些字符串是枚举值的名称,顾名思义。

EDIT: Should have suggested the System.Enum.GetValues method instead. Oops.

编辑:应该建议使用System.Enum.GetValues方法。哎呀。

#1


3934  

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

#2


573  

It looks to me like you really want to print out the names of each enum, rather than the values. In which case Enum.GetNames() seems to be the right approach.

在我看来,你真的想要打印每个枚举的名称,而不是值。在这种情况下,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);
    }
}

By the way, incrementing the value is not a good way to enumerate the values of an enum. You should do this instead.

顺便说一下,递增值不是枚举枚举值的好方法。你应该这样做。

I would use Enum.GetValues(typeof(Suit)) instead.

我会使用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());
    }
}

#3


288  

I made some extensions for easy enum usage, maybe someone can use it...

我做了一些扩展以便轻松使用枚举,也许有人可以使用它...

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

The enum itself must be decorated with the FlagsAttribute

枚举本身必须使用FlagsAttribute进行修饰

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

#4


148  

Some versions of the .NET framework do not support Enum.GetValues. Here's a good workaround from Ideas 2.0: Enum.GetValues in Compact Framework:

某些版本的.NET框架不支持Enum.GetValues。以下是Ideas 2.0中的一个很好的解决方法:Compact Framework中的Enum.GetValues:

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

As with any code that involves reflection, you should take steps to ensure it runs only once and results are cached.

与涉及反射的任何代码一样,您应该采取措施确保它只运行一次并缓存结果。

#5


85  

I think this is more efficient than other suggestions because GetValues() is not called each time you have a loop. It is also more concise. And you get a compile-time error not a runtime exception if Suit is not an enum.

我认为这比其他建议更有效,因为每次循环时都不会调用GetValues()。它也更简洁。如果Suit不是枚举,则会出现编译时错误,而不是运行时异常。

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop has this completely generic definition:

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


82  

Why is no one using Cast<T>?

为什么没有人使用Cast ?

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

There you go IEnumerable<Suit>.

你去IEnumerable

#7


68  

You won't get Enum.GetValues() in Silverlight.

你不会在Silverlight中获得Enum.GetValues()。

Original Blog Post by Einar Ingebrigtsen:

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

#8


50  

Just to add my solution, which works in compact framework (3.5) and supports type checking at compile time:

只是添加我的解决方案,它在紧凑的框架(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();
}

- If anyone knows how to get rid of the T valueType = new T(), I'd be happy to see a solution.

- 如果有人知道如何摆脱T valueType = new T(),我很乐意看到解决方案。

A call would look like this:

一个电话看起来像这样:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

#9


44  

I think you can use

我想你可以用

Enum.GetNames(Suit)

#10


42  

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

#11


37  

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

I've heard vague rumours that this is terifically slow. Anyone know? – Orion Edwards Oct 15 '08 at 1:31 7

我听到一些含糊不清的谣言说这种情况非常缓慢。谁知道? - 猎户座爱德华兹08年10月15日1:31 7

I think caching the array would speed it up considerably. It looks like you're getting a new array (through reflection) every time. Rather:

我认为缓存阵列会大大加快它的速度。看起来你每次都会得到一个新阵列(通过反射)。而是:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

That's at least a little faster, ja?

这至少要快一点,ja?

#12


21  

Three ways:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

Not sure why was GetEnumValues introduced on type instance, it isn't very readable at all for me.

不确定为什么GetEnumValues在类型实例上引入,它对我来说根本不是很可读。


Having a helper class like Enum<T> is what is most readable and memorable for me:

像Enum 这样的助手类对我来说是最具可读性和难忘性的:

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

Now you call:

现在你打电话:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

One can also use sort of caching if performance matters, but I don't expect this to be an issue at all

如果性能很重要,也可以使用某种缓存,但我不认为这根本就是一个问题

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

#13


20  

What the hell I'll throw my two pence in, just by combining the top answers I through together a very simple extension

我将把我的两便士扔进去,只需将最顶层的答案结合在一起,我就可以通过一个非常简单的扩展

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)
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Clean simple and by @Jeppe-Stig-Nielsen s comment fast.

干净简单,并由@ Jeppe-Stig-Nielsen快速评论。

#14


19  

I use ToString() then split and parse the spit array in flags.

我使用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);
}

#15


19  

There are two ways to iterate an Enum:

迭代枚举有两种方法:

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

The first will give you values in form on a array of object, and the second will give you values in form of array of String.

第一个将在对象数组中为您提供表单中的值,第二个将以String数组的形式为您提供值。

Use it in foreach loop as below:

在foreach循环中使用它如下:

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

#16


13  

I do not hold the opinion this is better, or even good, just stating yet another solution.

If enum values range strictly from 0 to n - 1, a generic alternative:

如果枚举值严格范围从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;
    }
}

If enum values are contiguous and you can provide the first and last element of the enum, then:

如果枚举值是连续的,并且您可以提供枚举的第一个和最后一个元素,那么:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

but that's not strictly enumerating, just looping. The second method is much faster than any other approach though...

但这不是严格的枚举,只是循环。第二种方法比任何其他方法快得多......

#17


13  

If you need speed and type checking at build and run time, this helper method is better than using LINQ to cast each element:

如果在构建和运行时需要速度和类型检查,这个辅助方法比使用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[];
}

And you can use it like below:

你可以像下面这样使用它:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Of course you can return IEnumerable<T>, but that buys you nothing here.

当然你可以返回IEnumerable ,但是这里没有你买的东西。

#18


11  

here is a working example of creating select options for a DDL

这是为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()
      };

#19


9  

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

(The current accepted answer has a cast that I don't think is needed (although I may be wrong).)

(目前接受的答案有一个我认为不需要的演员(尽管我可能错了)。)

#20


8  

This question appears in Chapter 10 of "C# Step by Step 2013"

这个问题出现在“C#Step by Step 2013”​​的第10章中

The author uses a double for-loop to iterate through a pair of Enumerators (to create a full deck of cards):

作者使用双循环来迭代一对枚举器(以创建一副完整的卡片):

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

In this case, Suit and Value are both enumerations:

在这种情况下,Suit和Value都是枚举:

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

and PlayingCard is a card object with a defined Suit and Value:

和PlayingCard是一个具有定义的套装和价值的卡片对象:

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

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

#21


6  

I know it is a bit messy but if you are fan of one-liners, here is one:

我知道它有点乱,但如果你是单行的粉丝,这里有一个:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));

#22


6  

A simple and generic way to convert an enum to something you can interact:

将枚举转换为可以交互的内容的简单通用方法:

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

And then:

var enums = EnumHelper.ToList<MyEnum>();

#23


5  

What if you know the type will be an enum, but you don't know what the exact type is at compile time?

如果您知道类型将是枚举,但您不知道编译时的确切类型是什么?

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

The method getListOfEnum uses reflection to take any enum type and returns an IEnumerable of all enum values.

方法getListOfEnum使用反射来获取任何枚举类型并返回所有枚举值的IEnumerable。

Usage:

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

#24


1  

Add method public static IEnumerable<T> GetValues<T>() to your class, like

添加方法public static IEnumerable GetValues ()到你的类,比如

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

call and pass your enum, now you can iterate through it using foreach

调用并传递你的枚举,现在你可以使用foreach迭代它

 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }

#25


0  

Also you can bind to the public static members of the enum directly by using reflection:

您还可以使用反射直接绑定到枚举的公共静态成员:

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

#26


-1  

enum types are called "enumeration types" not because they are containers that "enumerate" values (which they aren't), but because they are defined by enumerating the possible values for a variable of that type.

枚举类型被称为“枚举类型”,不是因为它们是“枚举”值(它们不是)的容器,而是因为它们是通过枚举该类型变量的可能值来定义的。

(Actually, that's a bit more complicated than that - enum types are considered to have an "underlying" integer type, which means each enum value corresponds to an integer value (this is typically implicit, but can be manually specified). C# was designed in a way so that you could stuff any integer of that type into the enum variable, even if it isn't a "named" value.)

(实际上,这有点复杂 - 枚举类型被认为具有“底层”整数类型,这意味着每个枚举值对应一个整数值(这通常是隐式的,但可以手动指定).C#是设计的在某种程度上,你可以将任何类型的整数填充到枚举变量中,即使它不是“命名”值。)

The System.Enum.GetNames method can be used to retrieve an array of strings which are the names of the enum values, as the name suggests.

System.Enum.GetNames方法可用于检索字符串数组,这些字符串是枚举值的名称,顾名思义。

EDIT: Should have suggested the System.Enum.GetValues method instead. Oops.

编辑:应该建议使用System.Enum.GetValues方法。哎呀。