C# Iterating through an enum? (Indexing a System.Array)
我有以下代码:
1 2 3 4 5 6 7 8 9 10 11 | // 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] ); } |
但是,我不能索引值。有更简单的方法吗?
或者我完全错过了什么!
1 2 3 4 5 6 |
或者,可以强制转换返回的System.Array:
1 2 3 4 5 6 7 |
但是,您能确定getValues返回值的顺序与getNames返回名称的顺序相同吗?
您需要强制转换数组-返回的数组实际上是所请求的类型,即,如果您请求
1 |
然后是
可以将该数组强制转换为不同类型的数组:
1 |
或者如果需要整数值:
1 |
当然,您可以迭代那些强制转换的数组:)
字典列表怎么样?
1 2 3 4 5 |
当然,您可以将字典值类型更改为枚举值是什么。
另一个解决方案,具有有趣的可能性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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; } } |
这是另一个。我们需要为我们的枚举值提供友好的名称。我们使用System.ComponentModel.DescriptionAttribute为每个枚举值显示自定义字符串值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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; } } |
在使用中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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"
旧问题,但使用Linq的
1 2 3 4 5 6 | var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>(); foreach(var val in values) { Console.WriteLine("Member: {0}",val.ToString()); } |
使用foreach循环怎么样,也许你可以使用它?
1 2 3 4 5 6 | int i = 0; foreach (var o in values) { print(names[i], o); i++; } |
也许是那样?
在enum.getValues结果中,强制转换为int将生成数值。使用ToString()生成友好名称。不需要其他调用Enum.GetName。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 +" "); } 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 */ |
您可以使用格式字符串来简化这个过程。我在用法消息中使用以下代码段:
1 2 3 4 5 | 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说明符,它的作用就像标志总是存在一样。
请参见enum.format()。
数组有一个getValue(int32)方法,可以使用该方法在指定的索引处检索值。
数组值
古老的问题,但3dave的回答提供了最简单的方法。我需要一个小助手方法来生成一个SQL脚本来解码数据库中的枚举值以进行调试。效果很好:
1 2 3 4 5 6 | 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,"; } |
我用的是静态方法,所以用法是:
1 | var cheater = MyStaticClass.EnumToCheater<MyEnum>() |
下面是一个简单的方法来迭代您的自定义枚举对象
1 2 3 4 5 | For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum)) Print([Enum].GetName(GetType(MyEnum), enumValue).ToString) Next |