2017-10-19 63 views
1

我在寫一些通用的枚舉鑄造邏輯,和我遇到一個奇怪的現象附帶Enum.ToObject方法:分配一個InvalidValue以枚舉變量(這是爲什麼不拋出異常?)

[TestClass] 
public class UnitTest1 
{ 
    public enum FixedSet 
    { 
     Value1 = 1, 
     Value2 = 2, 
     Value3 = 3 

    } 

    [TestMethod] 
    public void TestMethod1() 
    { 

     try 
     { 
      var intVal = 123; 
      FixedSet actual = (FixedSet)Enum.ToObject(typeof(FixedSet), intVal); 
      Assert.Fail("Thought an exception should have occured"); 
     }catch(Exception e) 
     { 
      //should have thrown an exception 
     } 
    } 
} 

```

我希望這會拋出某種異常,因爲123不是給定枚舉類型的值,但是,我可以將它設置爲此FixedSet變量的值。

爲什麼允許這樣做?我一直認爲這會失敗,因爲C#是強類型語言,這是一個強烈的定義枚舉...

+0

不,它不會像這樣工作。 'Enum'是它的基礎類型。 –

+0

複製粘貼代碼,你會看到它失敗。問題是「爲什麼這不會拋出異常」 –

+0

[Define「fail」。](https://dotnetfiddle.net/Xt38n6)你的意思是它得到了斷言? –

回答

6

根據ISO IEC 23270(2006):

尤其的任何值枚舉的基礎類型可以將 轉換爲枚舉類型,並且是該枚舉類型的明確有效值。

枚舉不從基礎類型「繼承」(它只是一種語法)。根據相同的ISO,枚舉隱含地從System.EnumSystem.ValueType繼承。

類型System.Enum是抽象基類所有枚舉類型(這是不同的,並從基礎類型的枚舉 類型的不同)

注意System.Enum本身不是一個枚舉類型。相反,它是一個 類型,從中派生所有的枚舉類型。從類型類型System.Enum 繼承System.ValueType(§11.1.1),這反過來,從類型object

如果你想檢查是否枚舉的價值是「共同」感覺有效,可以 繼承使用Enum.IsDefined方法。

+0

啊,所以事實上,一個枚舉的默認數據類型是一個int,基於繼承,它必須遵循父類的要求。這就說得通了。感謝澄清「它不這樣工作」這是更具建設性 –

+0

@NathanTregillus不,枚舉不從int繼承。我會在一秒鐘內更新我的答案。 –