2011-08-25 49 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)) ...