2011-07-01 45 views
6

我很好奇,一旦你拋出System.ComponentModel.InvalidEnumArgumentException,你將如何維護你的代碼。如何維護InvalidEnumArgumentException的代碼?

基本上我有一個switch語句是這樣的:

switch (enumValue) 
{ 
    case MyEnum.Value1: 
     break; 

    case MyEnum.Value2: 
     break; 

    default: 
     throw new InvalidEnumArgumentException(); 
} 

如果我決定更多的值在將來添加到MyEnum,例如,Value3Value4什麼?那意味着我最終會拋出一個誤導性的例外。我將如何防止這種情況?

我應該在投擲之前使用反射嗎?我應該拋出什麼例外情況?我在尋找建議。


我剛剛在幾分鐘前發現了這個異常,所以也許我在錯誤的上下文中看到了這個。如果某個枚舉參數不受支持(這種情況下Value3Value4不被支持),這個異常會拋出嗎?

回答

0

我不會在這種情況下使用你正在使用的異常。由於enumValue是MyEnum類型(我假設?)它永遠不能包含無效的枚舉值。如果你的開關基於枚舉的值,如果它們不能識別這個值,那麼你需要拋出一個適當的異常(可能只是一個正常的ArgumentException?),但在大多數情況下,我猜你會讓代碼對於未知的枚舉值不起作用。

+2

這是錯誤的。根據[此設計指導原則的補充](http://blogs.msdn.com/b/kcwalina/archive/2004/05/18/134208.aspx),「將任何整數值轉換爲枚舉是合法的即使該值未在枚舉中定義。「 –

+0

當然,一個'enum'值可能是無效的。您可以將不是枚舉值之一的數字轉換爲enum類型。或者這可能是由枚舉定義在使用擴展枚舉更新的其他程序集中定義的。 –

+1

好吧,我從來沒有。看起來我今天學到了一些新東西。 :-) – DoctorMick

0

我相信你正在尋找它在錯誤的情況下,如果這些人不是枚舉但被在這種情況下,基於一些業務規則,使某些特定的值作爲規則的增加,你會觸摸了相關代碼像這些將納入新的。所以如果你修改了Enum,那麼你應該看看這些變化。

+0

如果有許多這樣的switch語句在同一個枚舉上作用的地方,可以有工廠根據枚舉值創建多態對象,並將該功能從開關移動到該對象的方法 – driushkin

8

你所說的問題取決於上下文,如果一個方法接收一個枚舉作爲參數,它必須指定它支持什麼值,以及它如何處理未知的枚舉值。

如果您添加更多的枚舉選項,您需要決定如何處理,即使您沒有在默認情況下拋出異常。

請注意,該異常特別有用,因爲您可以將任何整數作爲枚舉值傳遞。

例如:

enum Foo { A, B } 

static int Bar(Foo f) 
{ 
    switch (f) 
    { 
     case Foo.A: 
      return 1; 
     case Foo.B: 
      return 2; 
     default: 
      throw new InvalidEnumArgumentException("f", (int)f, typeof(Foo)); 
    } 
} 

static void Main() 
{ 
    Bar(Foo.A); 
    Bar((Foo)99); 
} 
+2

如果您只針對dot net 4.6或更高版本是用'nameof(f)'替換''f''字符串。 – skkeeper

1

爲了驗證傳入枚舉值使用下面的靜態方法...

public void MyMethod(MyEnum e) 
{ 
    if (!Enum.IsDefined(typeof(MyEnum), e)) 
     throw new InvalidEnumArgumentException("e", (int)e, typeof(MyEnum)); 

...你並不需要改變,如果新的枚舉檢查值將在未來添加。

+1

如果MyEnum使用新值進行擴展,那麼'!Enum.IsDefined(typeof(MyEnum),e))'將爲它們返回true,所以這個測試很可能永遠不會失敗。 – Spook

+0

@Spook但是如果MyEnum沒有爲'0'定義一個入口並且e在MyEnum e中隱含地賦予了一個默認值,它將失敗。 MyMethod(e);'或者代碼在數字上設置'e'的值。關鍵是C#本身不會強制'e'成爲'MyEnum'的有效值,簡而言之,你不能假設任何東西。 – binki

4

如果我決定在將來爲MyEnum添加更多值,例如Value3和Value4會怎樣?這意味着我最終會拋出一個誤導性的例外。我將如何防止這種情況?

當你使用InvalidEnumArgumentException關鍵的還是要了解的是說法。通過拋出異常,您說該方法的參數無效。 (InvalidEnumArgumentException派生自ArgumentException。)這並不一定意味着該值不是enum的成員。所以我不認爲這是誤導。