2011-08-25 53 views
18

我正在研究一个Web服务方法,它将接收一个int数组作为参数,然后在方法内部,我将数组中的值转换为枚举值,并将它们存储在一个枚举列表。但是,如果传入的值不在枚举中,则将其添加到枚举列表中而不会出现问题。没有InvalidCastException,没什么。我做了一个试验项目,看起来像这样:C#枚举数组接受一个错误的值

static class Program 
{ 
    static void Main(string[] args) 
    { 
     List<TestValues> values = new List<TestValues>() { 
      TestValues.Value1, 
      TestValues.Value2, 
      (TestValues)15 
     }; 

     foreach (var val in values) 
      Console.WriteLine(val); 

     Console.Read(); 
    } 

    enum TestValues 
    { 
     Value1 = 2, 
     Value2 = 4, 
     Value3 = 8 
    } 
} 

当我运行它时,输出为:

Value1 
Value2 
15 

对于我的web服务,我将实现一个验证,所以这不会hapen在所有。但是......这很奇怪!运行时不应该抛出一个InvalidCastExceptionArgumentOutOfRangeException或类似的东西?由于我得到了枚举列表(而不是int值),我希望值限制为enum的值(这是枚举的用途)。

我错过了什么吗?这是一个.NET错误,C#错误还是有我不知道与枚举?

+0

+1混日子的问题 – Tigran

+1

阅读本之一: [为什么铸造INT无效的枚举值不抛出异常?] [1] [1]:http://stackoverflow.com/问题/ 6413804/why-does-casting-int-to-invalid-enum-value-not-throw-exception – vinayvasyani

回答

19

您可以将任何值分配给底层类型允许的enum。默认情况下,基础类型为int,因此您可以将任何int值分配给enum

造成这种情况的主要原因是因为如果你有一个[Flags]枚举,能够分配复合值:

[Flags] 
public enum MyFlags 
{ 
    A = 1, 
    B = 2 
} 

MyFlags flags = (MyFlags)3; // Equivalent to setting A and B 

最好你只是用枚举值要做到这一点,虽然:

MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3 

重要的是要注意的,当然,前提是该[Flags]属性不需要启用这个任务是很重要的。所有enum都有此属性,由设计。

正如许多人指出的那样,你可以使用Enum.IsDefined(),以确定是否一个特定的值是有效的给定enum。这应该有助于您的验证。

+0

我完全忘了'[Flags]',因为我很少使用它。对我来说,这似乎是一个明显的优势,但对于更常用的枚举有点奇怪。顺便说一下,评论和其他答案为主题提供了很好的补充链接。 – Raphael

1

您总是可以将任何int值转换为基于int的枚举。这是设计的,因为如果必须检查所有合法值,演员阵容会慢很多。

+1

我不认为速度是决定性的因素。 –

+0

@亨克 - 请详细说明,除了旗帜之外还有其他因素吗? –

1

要确定是否在enum中定义了指定的int,您可以使用Enum.IsDefined

Enum.IsDefined(typeof(TestValues), 15); 
5

是的,在转换为枚举值时没有检查已定义的值。

可以使用IsDefined方法来检查,如果一个特定的值定义:

if (Enum.IsDefined(typeof(TestValues), value)) ...