Enum as a parameter in a method, looping through the enum produces invalid cast
这就是我所拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private IEnumerable<SelectListItem> GetAllEnumValues(Enum enumValues) { var allEnumValues = new List<SelectListItem>(); var values = Enum.GetValues(enumValues.GetType()); foreach (var selectedItem in values) { allEnumValues.Add(new SelectListItem { Value = ((int)selectedItem).ToString(), Text = selectedItem.ToString() }); } return allEnumValues.AsEnumerable(); } |
方法的调用方式如下:
1 | AllAgencies = GetAllEnumValues((AgencyCodes) 0) |
构建很好,但是当实际使用该方法时,我得到"指定的强制转换无效"。死亡的黄色屏幕在.add行上。我需要selectListItem的值是实际的枚举数,只是强制转换为字符串。到目前为止,我尝试了所有这些方法:C遍历枚举?(索引System.Array)、C和ForEach中的枚举,如何枚举枚举?最后,我总是以同样的错误结束。我正在使用.NET 4.0。
这通常意味着您的枚举不是基于
1 2 3 | enum AgencyCodes : short { ... } |
不能将枚举取消绑定到错误的值类型。
如果需要数值,可以使用
现在,多亏了表情树的魔力…两类:
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | public static class EnumToString<T> { public static readonly Func<T, string> Do; static EnumToString() { Type type = typeof(T); if (!type.IsEnum) { throw new ArgumentException(); } Type baseType = type.GetEnumUnderlyingType(); var par1 = Expression.Parameter(typeof(T)); var cast = Expression.Convert(par1, baseType); Expression<Func<object, string>> toString = p => p.ToString(); var body = (MethodCallExpression)toString.Body; var toString2 = Expression.Call(cast, body.Method); Do = Expression.Lambda<Func<T, string>>(toString2, par1).Compile(); } } public static class EnumToObject<T> { public static readonly Func<T, object> Do; static EnumToObject() { Type type = typeof(T); if (!type.IsEnum) { throw new ArgumentException(); } Type baseType = type.GetEnumUnderlyingType(); var par1 = Expression.Parameter(typeof(T)); var cast1 = Expression.Convert(par1, baseType); var cast2 = Expression.Convert(cast1, typeof(object)); Do = Expression.Lambda<Func<T, object>>(cast2, par1).Compile(); } } static void Main() { string str = EnumToString<MyEnum>.Do(MyEnum.Foo); //"1" object obj = EnumToObject<MyEnum>.Do(MyEnum.Foo); // (int)1 } |
第一个,
要使用它们,您必须将类更改为如下类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 | IEnumerable<SelectListItem> GetAllEnumValues<T>() { // In truth, the array returned by Enum.GetValues **is** strongly typed // but is"downcasted" to Array. So we re-upcast it. T[] values = (T[])Enum.GetValues(typeof(T)); ... Value = EnumToString<T>.Do(selectedItem), // or Value = EnumToObject<T>.Do(selectedItem).ToString(), } |
但请注意,所有这些几乎都是无用的,因为有一个特殊的格式化程序
1 2 3 4 5 | MyEnum enu = MyEnum.Something; // (where MyEnum.Something == 1) string str = enu.ToString("d"); // 1 Enum enu2 = enu; string str2 = enu2.ToString("d"); // 1 |
请参见枚举格式字符串
根据你提供的信息,我怀疑
1 | Value = ((int)selectedItem).ToString() |
导致了你的问题。应该是
1 | Value = (int)selectedItem; //if you need number and value is of type int |
或
1 | Value = selectedItem.ToString(); //if you need text and value is of type string |