2012-08-16 136 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