2010-01-20 2 views
7

Je pensais que je l'ai vu tout mais ... :)C# Generics, comparant 2 chaînes Echoue sauf si spécifié explicitement

je travaillais sur un graphique générique de type chaîne,

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

le graphique est déclaré avec une contrainte de classe comme ceci:

public class Graph<T> where T : class 

Next i remplir le graphique avec des chaînes générées dynamiquement:

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

Jusqu'à présent, si bon, (Node est une classe interne contenant la valeur d'origine et une liste de références à d'autres noeuds (parce que son graphique))

Maintenant, lorsque je tente de créer des relations entre les différents nœuds, je dois rechercher le bon noeud en vérifiant sa valeur et c'est là que commence l'étrangeté.

Le code suivant, est une copie directe du résultat trouvé dans la fenêtre immidiate après avoir fait quelques tests:

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

Suis-je quelque chose de totalement disparu ou ne devrait pas Nodes.First() Valeur ==. "A" utilise une méthode de comparaison de chaînes. (Le compilateur JIT a des connaissances sur le type beeing utilisé à l'exécution, et avec cela, ses méthodes supportées, non?). Il me semble que quand on ne spécifie pas explicitement une chaîne, on fera une vérification de référence plutôt qu'un test de chaîne.

Ce serait formidable si quelqu'un pouvait me l'expliquer,

Merci à l'avance!

+3

Quel est le type statique de la propriété 'Value'? –

+0

Etes-vous sûr que la valeur est définie comme suit: public T Value {get; ensemble; } – albertein

Répondre

3

== est une méthode statique et donc pas virtuelle. La sélection de la méthode == à utiliser est effectuée au moment de la compilation, et non au moment de l'exécution. En fonction du type de compilation de l'objet, il est probable qu'il choisisse l'implémentation de == pour les objets qui se comparent par référence. Si vous utilisez plutôt les méthodes virtuelles Equals, cela fonctionnera comme prévu.

5

Si la propriété Value de vos nœuds est object, l'opérateur == dans

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

fera une comparaison par référence au lieu de comparer les chaînes.

8

Si les types ne sont pas entièrement connus à l'avance (c.-à-Value est seulement connu comme T, et ne sont pas strictement connu pour être une chaîne), les choses d'utilisation comme:

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

Bien sûr, vous pourriez lancer, mais dans ce cas vous auriez besoin d'un double casting ((string)(object)) qui est moche.

Si vous savez que les deux objets sont du même type (c.-à-d.deux T valeurs), vous pouvez utiliser:

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

L'avantage de ce qui précède est qu'il évite la boxe de struct et supports soulevé Nullable<T> opérateurs et IEquatable<T> en plus de Equals.

Questions connexes