2009-02-03 142 views
52

我从数据库中获得了一个Int16值,并且需要将其转换为枚举类型。不幸的是,这个代码层完全不了解对象,只知道通过反射可以收集的内容。Convert.ChangeType并转换为枚举?

因此,它最终会调用Convert.ChangeType,失败并显示无效的转换异常。

我发现了什么,我认为一个解决办法臭,像这样:

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

有没有更好的办法,让我没有通过这个字符串操作搬家?

这里,如果有人需要进行试验,可用于短,但完整的程序:

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

哎哟......我需要停下来试图回答这样的问题,我有我的咖啡前... – 2009-02-03 14:10:37

+0

我现在看到,Console.WriteLine也位于无权访问枚举类型的图层中。我完全误解了。删除了我的(愚蠢的)答案。 – GvS 2009-02-03 15:47:12

回答

74

Enum.ToObject(....是你在找什么!

C#

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

VB.NET

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

如果你做了很多枚举的转换尝试使用下面的类会为你节省很多的代码。

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

0

基础上@彼得的回答这里是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)的值,即使有一些通过null,-1000,500000,"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 
    } 
0

如果要存储一个枚举数据表中的,但不知道哪列是一个枚举并且它是一个字符串/ 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)); 
    } 
}