2009-02-03 143 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)); 
    } 
}