将超出范围的数字强制转换为C#中的枚举不会产生异常

将超出范围的数字强制转换为C#中的枚举不会产生异常,c#,exception,enums,casting,C#,Exception,Enums,Casting,以下代码不生成异常,而是将值4传递给tst。有人能解释这背后的原因吗 public enum testing { a = 1, b = 2, c = 3 } testing tst = (testing)(4); 因为您的枚举是基于int的,所以它可以接受int可以接受的任何值。而且,由于您明确地(通过强制转换)告诉编译器可以将4强制转换到枚举中,因此可以这样做。每个枚举都有一个用于表示的底层数字类型(例如int)。即使一个值没有名称,它也是枚举可能具有的值。

以下代码不生成异常,而是将值4传递给tst。有人能解释这背后的原因吗

 public enum testing
 { 
    a = 1,
    b = 2,
    c = 3
 }

testing tst = (testing)(4);

因为您的枚举是基于int的,所以它可以接受int可以接受的任何值。而且,由于您明确地(通过强制转换)告诉编译器可以将4强制转换到枚举中,因此可以这样做。

每个枚举都有一个用于表示的底层数字类型(例如int)。即使一个值没有名称,它也是枚举可能具有的值。

在C#中,与Java不同,枚举不被检查。您可以具有基础类型的任何值。这就是为什么检查您的输入非常重要的原因

if(!Enum.IsDefined(typeof(MyEnum), value))
     throw new ArgumentOutOfRangeException();

其他人没有说的:通过强制转换,您告诉编译器您知道自己在做什么。所以,如果你告诉它,把它当作一个枚举值,它会的。其他的海报指出了为什么这仍然是允许的,因为C#编译器不允许很多不好的事情,即使你说你知道自己在做什么


如果不允许使用该值,那就太糟糕了,因为这样你就无法将标志值保存为int。或者,有人必须检查int是否是允许的组合之一,如果你使用标志枚举(带有可以组合在一起的值),这可能会非常多。

作为Java开发人员,我渴望C的一些特性(LINQ!),但在这里,Java真的做对了…@saua:不一定。这一点的主要优点是,您可以将这些值组合在一起,您还应该使用[Flags]属性来标记这些值。我知道,但我也可以使用枚举集来实现这一点,在我看来,枚举集不太像摆弄,而更像OO。一般来说,我更喜欢Java方式,其中Enum是伪装的对象,而不是伪装的Int。saua:一般来说,Java的枚举功能要强大得多。但在这个简单的例子中,.NET推理是无可挑剔的:运行时检查可能无效的标志组合非常耗时,而且在大多数情况下完全没有用处:除了很少使用外,你会为不使用的功能付出很多。我不确定第二段是否真的适用。这个评论是关于该语言中是否应该允许演员扮演,但问题是演员扮演什么角色,是否应该被检查。C#已选择允许
enum
类型的变量能够保存基础整数类型具有的任何值。另一种方法是,如果值在枚举中不可表示,则检查并抛出
InvalidCastException
。这也会发生在
enum.Parse
enum.TryParse
方法中,因此这里的问题与强制转换无关,而是与语言决策有关。