2009-11-05 52 views
7

我已經創建了兩個枚舉,我知道他們不是相同但我仍然認爲他們會是等於因爲他們的字符串表示以及他們的數字表示是相等的(甚至相同... )。C#中兩個枚舉何時相等?

換句話說:我想第一個測試通過,第二個測試失敗。但實際上,它們都失敗了。所以:C#中的兩個枚舉何時等於?還是有無法在C#中定義equals運算符?

謝謝!

public enum enumA {one, two} 

    public enum enumB {one, two} 

    [Test] 
    public void PreTest() 
    {   
    Assert.AreEqual(enumA.one,enumB.one); 
    Assert.AreSame(enumA.one, enumB.one); 
    } 

更新:1)所以到目前爲止答案都比較表示,無論是整數或字符串。枚舉本身總是不平等我收集?沒有辦法定義它的平等嗎?

+0

重複:http://stackoverflow.com/questions/1410131/comparing-two-enum-types-for-eivaivaiva – 2009-11-05 21:25:02

+0

@羅伯特:感謝您的鏈接,有趣和相關。顯然不重複:它要求枚舉的值。 – Peter 2009-11-05 21:30:04

回答

14

枚舉是強類型在C#中,因此enumA.one != enumB.one。現在,如果你將每個枚舉轉換爲它們的整數值,它們將是平等的。

Assert.AreEqual((int)enumA.one, (int)enumB.one); 

而且,我喜歡挑戰,由於它們具有相同的整數或字符串表示,他們應該是相同或等同的聲明。給定兩個枚舉NetworkInterfaceVehicleType,對於C#或.Net框架來說,通過值或字符串進行枚舉比較時,允許NetworkInterface.None等於VehicleType.None是不合邏輯的。但是,如果開發人員將強類型枚舉強制轉換爲整數或字符串,則語言或框架無法阻止這兩者成爲等號。

爲了進一步澄清,您不能覆蓋MyEnum.Equals爲了提供不同的等式方法。 .Net枚舉並不是他們在Java後期版本中的頭等公民,我希望C#允許與Enums進行更豐富的交互。

+1

在這裏要小心,這隻有在序數位置相同的情況下才是真實的。 – 2009-11-05 21:27:21

+1

謝謝。但是!=運算符不是我所追求的那個,而是等於()。即使不同的強類型可以相等我認爲,或者是不正確的? – Peter 2009-11-05 21:35:15

+0

@Peter:枚舉是結構,而且,你不能重載他們的任何方法。我還使用!=作爲更多的動詞,而不是實際的代碼片段。 @Tim:的確,這隻適用於他的案件和他的案件。 – user7116 2009-11-05 21:39:04

0
public enum enumA {one = 1, two = 2} 

    public enum enumB {one = 1, two = 2} 

    [Test] 
    public void PreTest() 
    {      
     Assert.AreEqual((int)enumA.one, (int)enumB.one); 
     // I don't think this one will ever pass 
     Assert.AreSame(enumA.one, enumB.one); 
    } 
1

如果你希望他們配合,扮演他們爲int

Assert.AreEqual((int)enumA.one,(int)enumB.one); 

會通過,因爲他們都是第一家上市的。如果你想讓他們匹配,因爲他們都說「一」,那麼你需要使用反思。

+2

我想,你可以這樣做,來檢查字符串值:Assert.AreEqual(enumA.one.ToString(),enumB.one.ToString()); – Jonas 2009-11-05 21:25:16

+0

或鑄造到字符串當然。 – Peter 2009-11-05 21:25:57

0

您可以嘗試鑄造他們:

Assert.AreEqual((int)enumA.one, (int)enumB.one); 
1

說實話,平等並不是直截了當的大部分時間。

我會傾向於創建一個實現IEqualityComparer(以及任何其他相等性測試,例如IsSame())的幫助類並使用它。

3

我是指你的C#語言規範3.0版,從這個報價已經從枚舉部分提取29頁:

「每個枚舉類型都有一個相應的積分類型,稱爲基礎類型的枚舉類型沒有顯式聲明基礎類型的枚舉類型的基礎類型爲int枚舉類型的存儲格式和可能值範圍由其基礎類型決定枚舉類型可以採用的值集是不受其枚舉類型的限制,特別是枚舉的基礎類型的任何值都可以轉換爲枚舉類型,並且是該枚舉類型的一個獨特的有效值。「

的.AreEqual方法確實測試等價,而第二測試身份。因此,簡單地每一個轉換爲它的基本類型(在這種情況下,int)和然後執行比較。

public enum enumA { one, two } 
public enum enumB { one, two } 
[Test] 
public void PreTest() 
{ 
     Assert.AreEqual((int)enumA.one,(int)enumB.one); 
     Assert.AreSame(enumA.one, enumB.one); 
} 
+0

Tx,你能提供一個鏈接嗎? – Peter 2009-11-05 21:37:05

2

不同於Java和C#不添加方法(如==操作符()),以枚舉提供任何便利。

我已經在過去需要更聰明的枚舉時做的是創造一個XHelper類(其中X是名稱的枚舉),並且我把所有的方法都放在它上面,例如:

public static bool EnumAHelper.EqualsEnumB(EnumA enumA, EnumB enumB) 
{ 
    return (int)enumA == (int)enumB; 
} 

雖然,我不記得遇到一個情況,我需要兩個不同的枚舉來表示相同的事情。

+0

非常好的評論(雖然之後)。我正在重寫一個我想兼容的現有類,所以它的枚舉也應該是一樣的。 – Peter 2009-11-05 22:31:51