枚举作为方法中的参数,在枚举中循环会产生无效的强制转换
本文关键字:枚举 转换 无效 方法 参数 循环 | 更新日期: 2023-09-27 18:27:34
这就是我所拥有的:
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();
}
这就是该方法的名称:
AllAgencies = GetAllEnumValues((AgencyCodes) 0)
Build很好,但当实际使用该方法时,我会在.Add行上看到"指定的强制转换无效"。我需要SelectListItem的值是实际的枚举数,只是转换为字符串。到目前为止,我尝试了所有这些:C#遍历枚举?(索引System.Array),C#和foreach中的枚举,如何枚举枚举?最后我总是犯同样的错误。我使用的是.NET 4.0。
这通常意味着您的枚举不是基于int
的,例如:
enum AgencyCodes : short {
...
}
不能将枚举取消装箱为错误类型的值。
如果您想要数值,可以使用Convert.ToInt32(selectedItem)
,然后对其执行ToString()
。如果enum
基于int
。(从技术上讲,除非enum
的值对int
来说太大,否则它会起作用)
现在,多亏了表达式树的魔力。。。两类:
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
}
第一个EnumToString<>
获取枚举值的值并将其转换为字符串。第二个方法将枚举值的值转换为其基类型(无论它是什么),并返回一个object
(因此它将基值框起来)(例如,您可以在其上执行.ToString()
)。
要使用它们,你必须将你的类更改为:
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(),
}
但请注意,所有这些几乎都是无用的,因为有一个特殊的格式化程序d
:
MyEnum enu = MyEnum.Something; // (where MyEnum.Something == 1)
string str = enu.ToString("d"); // 1
Enum enu2 = enu;
string str2 = enu2.ToString("d"); // 1
请参阅枚举格式字符串
根据您提供的信息,我怀疑
Value = ((int)selectedItem).ToString()
导致了您的问题。应该是
Value = (int)selectedItem; //if you need number and value is of type int
或
Value = selectedItem.ToString(); //if you need text and value is of type string