C#遍历枚举?(索引System.Array)


113

我有以下代码:

// Obtain the string names of all the elements within myEnum 
String[] names = Enum.GetNames( typeof( myEnum ) );

// Obtain the values of all the elements within myEnum 
Array values = Enum.GetValues( typeof( myEnum ) );

// Print the names and values to file
for ( int i = 0; i < names.Length; i++ )
{
    print( names[i], values[i] ); 
}

但是,我无法索引值。有没有更简单的方法可以做到这一点?

还是我完全错过了一些东西!

Answers:


204
Array values = Enum.GetValues(typeof(myEnum));

foreach( MyEnum val in values )
{
   Console.WriteLine (String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val));
}

或者,您可以强制转换返回的System.Array:

string[] names = Enum.GetNames(typeof(MyEnum));
MyEnum[] values = (MyEnum[])Enum.GetValues(typeof(MyEnum));

for( int i = 0; i < names.Length; i++ )
{
    print(names[i], values[i]);
}

但是,您可以确定GetValues以与GetNames返回名称相同的顺序返回值吗?


3
“但是,您可以确定GetValues以与GetNames返回名称相同的顺序返回值吗?” -这是一个很好的观点,我有话要说!我想你的第一个解决方案可能会提供一种可靠匹配值和字符串
TK。

您好,我之前已经提到过这样做时会出现“索引不匹配”的怀疑。但是,我还没有发现这是否真的令人担忧?有没有确定的情况可能使这个假设出错?谢谢!
2009年

如果要解决值不匹配的问题,您可能想将第二个“ val”强制转换为一个int,Enum.GetName(typeof(MyEnum), val), (int)val)其中输出提供了枚举名称和数字。
格雷格

GetValues和GetNames的返回顺序相同,即:“返回值数组的元素按枚举常量的二进制值(即,它们的无符号大小)排序。”
罗素·博罗戈夫

我相信您也可以通过调用Cast<T>结果直接使用LINQ :Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()...
jocull

33

您需要转换数组-返回的数组实际上是请求的类型,即myEnum[]如果您要求typeof(myEnum)

myEnum[] values = (myEnum[]) Enum.GetValues(typeof(myEnum));

然后values[0]等等


9

您可以将该数组转换为不同类型的数组:

myEnum[] values = (myEnum[])Enum.GetValues(typeof(myEnum));

或者,如果您想要整数值:

int[] values = (int[])Enum.GetValues(typeof(myEnum));

您当然可以迭代这些强制转换的数组:)


7

字典清单怎么样?

Dictionary<string, int> list = new Dictionary<string, int>();
foreach( var item in Enum.GetNames(typeof(MyEnum)) )
{
    list.Add(item, (int)Enum.Parse(typeof(MyEnum), item));
}

当然,您可以将字典值类型更改为任何枚举值。


我认为这是可行的方法,但是不幸的是,枚举位于我无法控制的代码领域!
传统知识。

1
我发现的唯一解决方案是获取实际的整数枚举值!
SharpC

5

另一种具有有趣可能性的解决方案:

enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

static class Helpers
{
public static IEnumerable<Days> AllDays(Days First)
{
  if (First == Days.Monday)
  {
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
     yield return Days.Saturday;
     yield return Days.Sunday;
  } 

  if (First == Days.Saturday)
  {
     yield return Days.Saturday;
     yield return Days.Sunday;
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
  } 
}

4

这是另一个。我们需要为我们的EnumValues提供友好的名称。我们使用System.ComponentModel.DescriptionAttribute为每个枚举值显示一个自定义字符串值。

public static class StaticClass
{
    public static string GetEnumDescription(Enum currentEnum)
    {
        string description = String.Empty;
        DescriptionAttribute da;

        FieldInfo fi = currentEnum.GetType().
                    GetField(currentEnum.ToString());
        da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
                    typeof(DescriptionAttribute));
        if (da != null)
            description = da.Description;
        else
            description = currentEnum.ToString();

        return description;
    }

    public static List<string> GetEnumFormattedNames<TEnum>()
    {
        var enumType = typeof(TEnum);
        if (enumType == typeof(Enum))
            throw new ArgumentException("typeof(TEnum) == System.Enum", "TEnum");

        if (!(enumType.IsEnum))
            throw new ArgumentException(String.Format("typeof({0}).IsEnum == false", enumType), "TEnum");

        List<string> formattedNames = new List<string>();
        var list = Enum.GetValues(enumType).OfType<TEnum>().ToList<TEnum>();

        foreach (TEnum item in list)
        {
            formattedNames.Add(GetEnumDescription(item as Enum));
        }

        return formattedNames;
    }
}

正在使用

 public enum TestEnum
 { 
        [Description("Something 1")]
        Dr = 0,
        [Description("Something 2")]
        Mr = 1
 }



    static void Main(string[] args)
    {

        var vals = StaticClass.GetEnumFormattedNames<TestEnum>();
    }

这将返回“ Something 1”,“ Something 2”


1
仅当描述是静态的时才有用。如果您的描述需要根据实例进行更改,则此方法将无效。
Llyle

3

使用foreach循环怎么样,也许您可​​以使用它?

  int i = 0;
  foreach (var o in values)
  {
    print(names[i], o);
    i++;
  }

这样的事?


我为此感到很高兴...但是我需要在“ sync”中同时访问名称和值...说“ names [2]与values [2]配对,我不确定如何实现”一个foreach循环!
传统知识。

我添加了一个示例-看看是否有帮助。
TWith2Sugars

3

旧问题,但是使用LINQ的方法稍微清洁一点 .Cast<>()

var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();

foreach(var val in values)
{
    Console.WriteLine("Member: {0}",val.ToString());     
}


2

您可以使用格式字符串简化此操作。我在使用情况消息中使用以下代码段:

writer.WriteLine("Exit codes are a combination of the following:");
foreach (ExitCodes value in Enum.GetValues(typeof(ExitCodes)))
{
    writer.WriteLine("   {0,4:D}: {0:G}", value);
}

D格式说明符将枚举值格式化为小数。还有一个X说明符,提供十六进制输出。

G说明符将枚举格式设置为字符串。如果将Flags属性应用于枚举,则也支持组合值。有一个F指示符,好像总是存在Flags。

请参见Enum.Format()。


2

在Enum.GetValues结果中,强制转换为int会产生数字值。使用ToString()产生友好名称。不需要其他对Enum.GetName的调用。

public enum MyEnum
{
    FirstWord,
    SecondWord,
    Another = 5
};

// later in some method  

 StringBuilder sb = new StringBuilder();
 foreach (var val in Enum.GetValues(typeof(MyEnum))) {
   int numberValue = (int)val;
   string friendyName = val.ToString();
   sb.Append("Enum number " + numberValue + " has the name " + friendyName + "\n");
 }
 File.WriteAllText(@"C:\temp\myfile.txt", sb.ToString());

 // Produces the output file contents:
 /*
 Enum number 0 has the name FirstWord
 Enum number 1 has the name SecondWord
 Enum number 5 has the name Another
 */

0

这是一种遍历自定义Enum对象的简单方法

For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum))

     Print([Enum].GetName(GetType(MyEnum), enumValue).ToString)

Next

1
我认为OP要求使用C#。
jm。

0

古老的问题,但3Dave的答案提供了最简单的方法。我需要一些辅助方法来生成Sql脚本,以对数据库中的枚举值进行解码以进行调试。效果很好:

    public static string EnumToCheater<T>() {
        var sql = "";
        foreach (var enumValue in Enum.GetValues(typeof(T)))
            sql += $@"when {(int) enumValue} then '{enumValue}' ";
        return $@"case ?? {sql}else '??' end,";
    }

我有一个静态方法,所以用法是:

var cheater = MyStaticClass.EnumToCheater<MyEnum>()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.