Supposons que je définis deux tuples:
Tuple tuple1 = new Tuple(1.0f, 2.0f, 3.0f, 4.0f); Tuple tuple2 = new Tuple(1.0f, 2.0f, 3.0f, 4.0f);
Si j’essaie de comparer les n-uplets, j’obtiens des résultats différents
bool result1 = (tuple1 == tuple2); // FALSE bool result2 = tuple1.Equals(tuple2); // TRUE
Je m’attendrais à ce que les deux appels retournent vrais. Qu’est-ce que ==
exactement?
Pour Tuple, le == compare les références d’object car il ne surcharge pas l’opérateur ==
. Puisque les objects sont équivalents, mais pas la même instance spécifique, Equals()
renvoie true
et ==
renvoie false
.
Beaucoup de types ne surchargent pas ==
, certains préfèrent garder une distinction entre Equals()
pour l’équivalence et ==
pour l’égalité de référence.
De plus, s’appuyer sur ==
pour l’équivalence peut conduire à une certaine étrangeté:
public bool AreSame(T first, T second) where T : class { return first == second; }
Le code ci-dessus vérifiera toujours l’égalité de référence car un générique non contraint est considéré comme un object
lors de la compilation. Ainsi, si la méthode n’est pas virtuelle, vous obtiendrez la version de l’object (même si le type, tel que ssortingng
overloads ==
).
Ainsi, cette utilisation du code ci-dessus:
var x = "Hello"; var y = "H"; // doing concat to avoid ssortingng interring AreSame(x, y+"ello");
Oui, les chaînes sont équivalentes, oui T
est une ssortingng
, mais ==
est lié à l’object ==
puisque le générique n’est pas contraint, donc cela renverra false
même si le même code avec des parameters de ssortingng
explicites renverrait true
.
==
compare les références d’object. La classe Tuple
ne surcharge pas l’opérateur ==
, vous devez donc utiliser .Equals
.
==
pour Tuple ne verra que les références et vous verrez donc que c’est faux.
PS: La manière recommandée est de faire quelque chose comme:
var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f)