2012-08-16 261 views
15

這個問題涉及到枚舉的鑄造泛型方法C#鑄造枚舉

給定一個枚舉

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

我可以創建枚舉的實例足夠簡單

short val = 4; 
Crustaceans crusty = (Crustaceans) val; 

內但是,如果

short val = 4; 
object obj = (object) val; 
Crustaceans crusty = (Crustaceans)obj; 

嘗試執行硬殼初始化時拋出運行時異常。

任何人都可以解釋爲什麼會發生這種情況,以及爲什麼做這樣的事情是不合法的。

不是我真的很想這樣做,但是當我嘗試獲得與泛型相似的事情時,我發現了一個問題,並且有效地發生了這種情況。即

public T dosomething<T>(short val) where T : new() 
{ 
    T result = (T)(object) val; 
    return result; 
} 

那麼什麼,我試圖做的是有與枚舉和非枚舉(不是那麼關鍵,但將是很好),可以設置爲短值工作沒有拋出異常的通用功能並實際初始化正確的枚舉值。

+21

難道是脫節指出,青蛙和蟾蜍不是甲殼類動物?:) – JTMon 2012-08-16 08:01:49

+1

可能重複[爲什麼我不能取消一個int作爲小數?](http://stackoverflow.com/questions/1085097/why-cant-i-unbox-an-int-as-a-decimal ) – 2012-08-16 08:03:42

+2

@sweetfa:雖然我指出的問題涉及int與decimal而不是枚舉,但它解釋了行爲(與裝箱和拆箱有關)。具體而言,接受的答案是指Eric Lippert撰寫的一篇文章:「[Representation and Identity](http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx )「,這很詳細地解釋了這一點。 – 2012-08-16 08:05:08

回答

30

這樣東西可能將幫助您:

public T dosomething<T>(object o) 
{ 
    T enumVal= (T)Enum.Parse(typeof(T), o.ToString()); 
    return enumVal; 
} 

但這將只用枚舉,爲明確原因使用Enum.Parse(..)

和使用等,例如:

object o = 4; 
dosomething<Crustaceans>(o); 

這將返回Toad in 你的的情況。

+1

這可以通過周圍的代碼檢查它是一個枚舉或像這樣 一個int如果(T被枚舉) – 2012-08-16 08:09:24

+0

改進版本(?): 公共ŤDoSomething的(對象o) { 變種enumType = typeof運算(T); if(!enumType.IsEnum) throw new ArgumentException(「Not an enum」); return(T)Convert.ChangeType(o,enumType); } – osexpert 2017-07-21 00:29:54

-1

有些情況下,當你不能使用泛型時(比如在WPF轉換器中,當你的值爲object時)。 在這種情況下,您不能投射到int,因爲枚舉類型可能不是int。 這是沒有泛型的一般方法。 的例子是一個WPF轉換器內給定的,但裏面的代碼是一般:

using System; 
using System.Windows; 
using System.Windows.Data; 

. 
. 
. 

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    var enumType = value.GetType(); 
    var underlyingType = Enum.GetUnderlyingType(enumType); 
    var numericValue = System.Convert.ChangeType(value, underlyingType); 
    return numericValue; 
} 
0

默認枚舉數字值具有類型= INT。 在您的代碼中,您希望將具有短類型的值轉換爲枚舉類型。爲此,你必須爲你的枚舉值設置short類型。這將工作:

public enum Crustaceans : short // <-- 
{ 
    Frog = 1, 
    Toad = 4 
} 

short @short = 1; 
object @object = @short; 

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog 

,如果你不希望更改默認枚舉值鍵入

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

object @object = Crustaceans.Frog; 

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog 

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

int @integer= 1; 

var @enum = (Crustaceans)@integer; // @enum = Crustaceans.Frog