int枚举无效转换

时间:2014-04-11 16:09:54

标签: c# casting enums

我正在测试我编写的一些代码,并想知道是否需要默认的案例处理。

让我们像这样定义MyEnum

public enum MyEnum 
{
    [Description("Value")]
    Value = 0,
    [Description("Other value")]
    OtherValue = 1,
}

我问自己的逻辑与此类似:

MyEnum val = (MyEnum)8;
if(val == MyEnum.Value)
    //do stuff
else if (val == MyEnum.OtherValue)
    //do other stuff
else 
    throw new ArgumentException("The value is not currently supported");

我的理由是没有默认情况,因为来自Enum中未定义的值的强制转换会在被我的代码捕获之前抛出异常。

所以我尝试了我在这里的例子,并且我很惊讶,演员没有抛出任何异常,这是我的默认案件处理巫婆抛出异常。

我的问题是:为什么intMyEnum的演员阵容有效?我知道在这个例子中,Enum的基础值是int,但我原本预计会从演员表中抛出异常。为什么有效?

3 个答案:

答案 0 :(得分:4)

默认情况下,枚举只是处理基础数据类型值Int32的一种奇特方式。你得到了命名值,你就失去了数学运算。没有规则只有声明中指定的值才是有效值,因此不会出现异常或编译器错误。

当您使用枚举作为标志时,这变得非常明显。

[Flags]
public enum Something
{
   Foo = 1,
   Bar = 2,
   Baz = 4
}

现在这样的事情

var x = Something.Foo | Something.Bar; // The value is 1 | 4 = 5

绝对没问题,你可以再次获得你从未命名过的值。这一切都归结为你错误的假设,即允许值的集合在某种程度上受到限制,并且正如其他答案所指出的那样,指出情况并非如此。

答案 1 :(得分:1)

这是设计上的。请参阅C#规范 4.1.9枚举类型

  

枚举类型是具有命名常量的不同类型。枚举类型的值集与集合的值相同   基础类型的值。枚举类型的值不是   将限制为指定常量的值。

实际上,枚举只是一组命名的文字字段(它们被命名为枚举类型的常量)和一个保存枚举实例值的特殊字段:

.class public auto ansi sealed MyEnum
    extends [mscorlib]System.Enum  
{
    .field public static literal valuetype Namespace.MyEnum Value = int32(0)
    .field public static literal valuetype Namespace.MyEnum OtherValue = int32(1)
    .field public specialname rtspecialname int32 value__
}

如您所见,这是一个基础类型的简单字段,任何Int32值都可以分配给枚举变量。

答案 2 :(得分:0)

规范描述了这种行为:

14.5枚举值和操作

  

枚举类型可以采用的值集不受其限制   枚举成员。特别是,基础类型的任何值   枚举可以转换为枚举类型,并且是一个独特的有效值   枚举类型。