Convert.ChangeType并转换为枚举?

我从数据库中获得了一个Int16值,并且需要将其转换为枚举types。 不幸的是,这个代码层完全不了解对象,只知道通过reflection可以收集的东西。

因此,它最终会调用Convert.ChangeType失败,并产生无效的转换exception。

我发现我认为是一个臭的解决方法,就像这样:

 String name = Enum.GetName(destinationType, value); Object enumValue = Enum.Parse(destinationType, name, false); 

有没有更好的方法,以便我不必通过这个string操作?

这是一个简短但完整的程序,如果有人需要实验,可以使用这个程序:

 using System; public class MyClass { public enum DummyEnum { Value0, Value1 } public static void Main() { Int16 value = 1; Type destinationType = typeof(DummyEnum); String name = Enum.GetName(destinationType, value); Object enumValue = Enum.Parse(destinationType, name, false); Console.WriteLine("" + value + " = " + enumValue); } } 

Enum.ToObject(....是你正在寻找的!

C#

 StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5); 

VB.NET

 Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison) 

如果你做了很多的Enum转换尝试使用下面的类,它会节省你很多的代码。

 public class Enum<EnumType> where EnumType : struct, IConvertible { /// <summary> /// Retrieves an array of the values of the constants in a specified enumeration. /// </summary> /// <returns></returns> /// <remarks></remarks> public static EnumType[] GetValues() { return (EnumType[])Enum.GetValues(typeof(EnumType)); } /// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. /// </summary> /// <param name="name"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType Parse(string name) { return (EnumType)Enum.Parse(typeof(EnumType), name); } /// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. /// </summary> /// <param name="name"></param> /// <param name="ignoreCase"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType Parse(string name, bool ignoreCase) { return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase); } /// <summary> /// Converts the specified object with an integer value to an enumeration member. /// </summary> /// <param name="value"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType ToObject(object value) { return (EnumType)Enum.ToObject(typeof(EnumType), value); } } 

现在,而不是写(StringComparison)Enum.ToObject(typeof(StringComparison), 5); 你可以直接写入Enum<StringComparison>.ToObject(5);

基于@彼得的答案这里是Nullable<int>Enum转换的方法:

 public static class EnumUtils { public static bool TryParse<TEnum>(int? value, out TEnum result) where TEnum: struct, IConvertible { if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){ result = default(TEnum); return false; } result = (TEnum)Enum.ToObject(typeof(TEnum), value); return true; } } 

使用EnumUtils.TryParse<YourEnumType>(someNumber, out result)对于许多场景很有用。 例如,Asp.NET中的WebApi控制器没有针对无效的Enum参数的默认保护。 Asp.NET将只使用default(YourEnumType)值,即使有一些传递nulldefault(YourEnumType)"garbage string"或完全忽略参数。 而且, ModelState在所有这些情况下都是有效的,所以解决方法之一就是使用int? 键入自定义检查

 public class MyApiController: Controller { [HttpGet] public IActionResult Get(int? myEnumParam){ MyEnumType myEnumParamParsed; if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){ return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect"); } return this.Get(washingServiceTypeParsed); } private IActionResult Get(MyEnumType myEnumParam){ // here we can guarantee that myEnumParam is valid } 

如果你将一个Enum存储在一个DataTable中,但不知道哪一列是一个枚举,哪一个是一个string/ int,那么你可以这样访问这个值:

 foreach (DataRow dataRow in myDataTable.Rows) { Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-="); foreach (DataColumn dataCol in myDataTable.Columns) { object v = dataRow[dataCol]; Type t = dataCol.DataType; bool e = false; if (t.IsEnum) e = true; Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) + (e ? Enum.ToObject(t, v) : v)); } }