2010-01-20 5 views
7

ich dachte, dass ich alles, aber diese gesehen habe ... :)C# Generics, Vergleich 2 Strings fail sofern nicht anders angegeben ausdrücklich

Ich war auf einem generischen Graph vom Typ String arbeiten,

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

graph ist mit einer Klasse-Einschränkung wie folgt erklärt:

public class Graph<T> where T : class 

Next i die Grafik mit einigen dynamicly erzeugten Strings aufzufüllen:

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

weit so gut, also (Node ist eine interne Klasse den ursprünglichen Wert und eine Liste von Verweisen auf andere Knoten (weil sein ein Graph) enthält)

Nun, wenn ich versuche, die Beziehungen zwischen den verschiedenen zu schaffen Knoten, ich muss den rechten Knoten nachsehen, indem ich seinen Wert überprüfe und das ist wo die Seltsamkeit beginnt.

Der folgende Code ist eine direkte Kopie des Ergebnisses im immidiate Fenster gefunden, nachdem einige Tests machen:

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

Bin ich völlig fehlt etwas oder sollte nicht Nodes.First() Wert ==. "A" verwendet eine String-Vergleichsmethode. (Der JIT-Compiler kennt den Typ, der zur Laufzeit verwendet wird, und damit auch die unterstützten Methoden, richtig?). Es scheint mir so, als würde ich eine Zeichenfolge nicht explizit angeben, sondern eine Referenzprüfung anstelle eines Stringtests.

Es wäre toll, wenn jemand mir dies erklären könnte,

Vielen Dank im Voraus!

+3

Was ist der statische Typ der Eigenschaft "Value"? –

+0

Sind Sie sicher, dass der Wert wie folgt definiert ist: public T Value {get; einstellen; } – albertein

Antwort

3

== ist eine statische Methode und daher nicht virtuell. Die Auswahl der zu verwendenden == Methode erfolgt zur Kompilierzeit, nicht zur Laufzeit. Abhängig vom Kompilierungszeittyp des Objekts wird wahrscheinlich die Implementierung von == für Objekte ausgewählt, die durch Referenz verglichen werden.

Wenn Sie stattdessen die virtuellen Methoden Equals verwenden, wird dies wie erwartet funktionieren. Wenn

5

die Value Eigenschaft Ihrer Knoten ist object, die == Operator in

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

wird anstelle des Vergleichens Strings einen Vergleich mit dem Bezugs tun.

8

Wenn die Typen nicht vollständig Front bekannt up (dh Value nur als T bekannt ist, und ist nicht streng bekannt, dass ein String zu sein), die Dinge verwenden wie:

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

Natürlich Du könntest casten, aber in diesem Fall brauchst du eine Doppelbesetzung ((string)(object)), die hässlich ist.

Wenn Sie wissen, dass die beiden Objekte vom selben Typ sind (d. H.zwei T Werte), dann können Sie verwenden:

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

Der Vorteil der oben ist, dass es structs Boxen von und Stützen angehoben Nullable<T> Operatoren und IEquatable<T> zusätzlich zu Equals vermeidet.