C # 通过枚举进行迭代? (为 System.Array 建立索引)

我有以下密码:

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

但是,我不能索引值。有没有更简单的方法来做到这一点?

还是我错过了什么!

133437 次浏览

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

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

也许是这样?

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

但是,您能确保 GetValue 返回值的顺序与 GetNames 返回名称的顺序相同吗?

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

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

然后是 values[0]等等

您可以将 Array 强制转换为不同类型的 Array:

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

或者如果你想要整数值:

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

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

字典清单怎么样?

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

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

数组具有一个 GetValue (Int32)方法,您可以使用该方法检索指定索引处的值。

数组

下面是迭代自定义 Enum 对象的一种简单方法

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


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


Next

这是另一个。我们需要为 EnumValue 提供友好的名称。我们用了系统。组件模型。属性为每个枚举值显示自定义字符串值。

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

这将结束返回“某物1”,“某物2”

另一个解决方案,有着有趣的可能性:

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

您可以使用格式字符串来简化这个过程:

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 格式说明符将枚举值格式化为十进制。

G 说明符将枚举格式化为字符串。如果将 Flags 属性应用于枚举,则也支持组合值。有一个 F 说明符,它的作用就好像旗帜总是存在一样。

参见 Enum.Format ()。

这是个老问题了,但是使用 LINQ 的 .Cast<>()的方法要简单一些

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


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

在 Enum 中。结果,强制转换为 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
*/

这是个古老的问题,但3Dave 的回答提供了最简单的方法。我需要一个小小的 helper 方法来生成一个 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>()