2010-01-20 9 views
7

我想我已經看到了這一切,但這個... :)C#泛型,比較兩個字符串失敗,除非明確指定

我工作的一個字符串類型的通用圖形,

Graph<string> graph = new Graph<string>(); 

圖表聲明一個類約束是這樣的:

public class Graph<T> where T : class 

接下來我填補了圖形的一些動態地生成的字符串:

for (char t = 'A'; t < 'J'; t++) 
{ 
    GraphPrim.Add(t.ToString()); 
} 

到目前爲止好,(Node是包含原始值,(到其他節點的引用列表,因爲它是一個圖)一個內部類)

現在,當我嘗試建立不同的關係節點,我必須通過檢查它的值來查找正確的節點,並在那裏出現奇怪的地方。

下面的代碼,是在做一些測試後的結果直接拷貝在immidiate窗口發現:

Nodes.First().Value 
"A" 
Nodes.First().Value == "A" 
false 
Nodes.First().Value.ToString() == "A" 
true 

我完全失去了一些東西或不應該Nodes.First()==值。 「A」使用字符串比較方法。 (JIT編譯器具有關於運行時使用的類型信息的知識,以及它支持的方法,對吧?)。在我看來,當不明確指定一個字符串時,它會執行引用檢查而不是字符串測試。

這將是偉大的,如果有人能夠向我解釋這一點,

在此先感謝!

+3

Value屬性的靜態類型是什麼? –

+0

您確定該值定義爲: public T Value {get;組; } – albertein

回答

3

==是一種靜態方法,因此不是虛擬的。在編譯時選擇使用哪種==方法,而不是運行時。根據對象的編譯時間類型,它可能選擇==的實現,以便通過引用進行比較。

如果您使用虛擬Equals方法,它將按照您的預期工作。

5

如果節點的Value屬性爲object,該==運營商

Nodes.First().Value == "A" 

會做參照,而不是比較字符串的比較。

8

如果類型不完全知曉前面(即Value僅稱爲T,並且不嚴格稱爲是一個字符串),使用了諸如:

object.Equals(Nodes.First().Value,"A") 

當然,你可以演員,但在這種情況下,你需要一個醜陋的雙演員((string)(object))。

如果您知道這兩個對象是相同的類型(即,2個T值),那麼你可以使用:

EqualityComparer<T>.Default.Equals(x,y) 

上述的優點是,它避免了結構的拳擊和支持解除Nullable<T>運營,而且除了EqualsIEquatable<T>