2012-08-15 155 views
11

我有一個枚舉,如:爲什麼我們需要在C#中類型轉換枚舉

public enum Test:int 
{ 
    A=1, 
    B=2 
} 

所以在這裏,我知道我的枚舉是一個int類型,但如果我想這樣做以下:

int a = Test.A; 

這不起作用。

如果我有一個類,如:

public class MyTest 
{ 
    public static int A =1; 
} 

我可以說,

int a = MyTest.A; 

這裏,我並不需要投A明確詮釋。

+0

http://stackoverflow.com/questions/97391/how-to-get-the-underlying-value-of-an-enum – 2kay 2012-08-15 12:00:42

+2

這是一個設計選擇。我猜C#發明者認爲它更安全和/或更具可讀性。 – 2012-08-15 12:01:57

+0

這種情況會有什麼令人信服的理由? – 2012-08-15 12:02:46

回答

3

有了更新的例子:

public class MyTest 
{ 
    public static int A =1; 
} 

與用法:

int a = MyTest.A; 

如何枚舉看。枚舉看起來更像(評論是,我們從一個真正的枚舉不同的地方):

public struct MyTest /* Of course, this isn't correct, because we'll inherit from System.ValueType. An enum should inherit from System.Enum */ 
{ 
    private int _value; /* Should be marked to be treated specially */ 
    private MyTest(int value) /* Doesn't need to exist, since there's some CLR fiddling */ 
    { 
     _value = value; 
    } 

    public static explicit operator int(MyTest value) /* CLR provides conversions automatically */ 
    { 
     return value._value; 
    } 
    public static explicit operator MyTest(int value) /* CLR provides conversions automatically */ 
    { 
     return new MyTest(value); 
    } 

    public static readonly MyTest A = new MyTest(1); /* Should be const, not readonly, but we can't do a const of a custom type in C#. Also, is magically implicitly converted without calling a constructor */ 

    public static readonly MyTest B = new MyTest(2); /* Ditto */ 
} 

是的,你可以輕鬆到達「底層」 int值,但AB值仍強烈鍵入爲MyTest。這確保你不會意外地在他們不合適的地方使用它們。

+0

這是一個非常好的例子,謝謝,現在我明白爲什麼我必須做鑄造。意味着我每次使用該值都必須拆箱。 – 2012-08-15 12:57:10

+0

這不是*枚舉枚舉的外觀 - 因爲你可以將*任何*'int'值轉換爲具有該類型基礎值的枚舉值。不幸的是,在這方面,枚舉是「不安全的」。而且,它們是值類型而不是引用類型。 – 2012-08-15 13:35:27

+1

@Praveen:不,這並不意味着你必須拆箱。從枚舉值轉換爲其數值不涉及裝箱或拆箱。 – 2012-08-15 13:36:38

18

所以在這裏,我知道我的枚舉是一個int類型

不,不是這樣的。它有一個的底層類型的int,但它是一個單獨的類型。哎呀,這是第一個枚舉的一半 - 你可以保持類型分開。

當您想要在枚舉值和它的數字等價值之間進行轉換時,您投下了它 - 並不那麼痛苦,並且它可以讓您的代碼在類型安全性方面保持更清晰。基本上這是其中稀罕的事情之一是要做的事情是明確的。

編輯:一個怪胎,你應該知道的是,有從恆定值0到枚舉類型的隱式轉換:

Test foo = 0; 

事實上,在MS實現,它可以是任何種常數0:

Test surprise = 0.0; 

這是一個錯誤,但其中一個已經太晚了修復:)

我相信這個隱式轉換的其餘部分是爲了更簡單地檢查是否在flags枚舉中設置了任何位,以及使用「0值」的其他比較。就我個人而言,我不是那個決定的粉絲,但至少值得注意。

+0

我的意思是我知道的枚舉類型爲int,是不是如此混亂,我可以告訴大家,我的枚舉有潛在的int類型,但我不能使用它像一個int。 – 2012-08-15 12:03:41

+2

@Praveen:不,枚舉不是int。枚舉具有int的*存儲表示*,但它是一個單獨的類型。 *您不應該*使用它像一個int沒有明確這樣做... – 2012-08-15 12:04:36

+1

@Praveen:*「我知道枚舉爲int」 * - 您直觀地瞭解到它代表'int',是的。但就編譯器而言,這是另一種類型。就像創建一個沒有其他成員而不是一個公共'int'的類一樣。你「知道它只是一個'int'」,但它實際上是一個完全不同的類型,它恰好在內部將其唯一的數據成員表示爲int。 – David 2012-08-15 12:09:14

3

枚舉值不是int類型。 int是枚舉的基本類型。枚舉在技術上是整數,但邏輯上(從C#語言的角度來看)不是。如果沒有明確指定另一個枚舉,則默認爲intSystem.Int32)是所有枚舉的基類型。

2

您枚舉類型爲Test。這不僅僅是因爲你的枚舉具有整數值而不是int

你可以投你的枚舉得到int值:

int a = (int) Test.A; 
+0

我知道我可以施放它,但問題是爲什麼我需要施放它? – 2012-08-15 12:04:36

+0

我的猜測是,這是一個讓我們明確施放的設計決定。 – davenewza 2012-08-15 12:07:30

相關問題