我正在测试我编写的一些代码,并想知道是否需要默认的案例处理。
让我们像这样定义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中未定义的值的强制转换会在被我的代码捕获之前抛出异常。
所以我尝试了我在这里的例子,并且我很惊讶,演员没有抛出任何异常,这是我的默认案件处理巫婆抛出异常。
我的问题是:为什么int
到MyEnum
的演员阵容有效?我知道在这个例子中,Enum的基础值是int
,但我原本预计会从演员表中抛出异常。为什么有效?
答案 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枚举值和操作
枚举类型可以采用的值集不受其限制 枚举成员。特别是,基础类型的任何值 枚举可以转换为枚举类型,并且是一个独特的有效值 枚举类型。