724 votes

Différence C # entre `==` et .Equals ()

J'ai une condition dans une application silverlight qui compare 2 chaînes, pour une raison quelconque, quand j'utilise == elle retourne false tandis que .Equals() renvoie true . Voici le code:

  if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
 {
// Execute code
 }

 if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
 {
// Execute code
 }
 

Une raison quelconque pour expliquer pourquoi cela se produit?

536voto

Mehrdad Afshari Points 204872

Lorsque == est utilisé sur un type de référence , il se résout à System.Object.ReferenceEquals .

Equals est juste une méthode virtual et se comporte comme tel, donc la version surchargée sera utilisée (ce qui, pour string compare le contenu).

448voto

BlueMonkMN Points 10838

INEXACT: String.Equals compare chaîne de contenu, mais "==" compare les références de l'objet. Si les deux chaînes de la comparaison de sont se référant à la même instance d'une chaîne, à la fois renvoie true, mais si l'une des chaînes a le même contenu et est venu à partir d'une source différente (est une instance distincte d'une chaîne de caractères), seulement Égale retournera true.

CORRECTION: La deuxième commentaire associé avec ce post est correct. Le code suivant illustre le problème:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

La sortie est:
Vrai Vrai Vrai
Faux Vrai Vrai
Faux Faux Vrai

58voto

JaredPar Points 333733

Ce qu' == et .Est égal n'est à la fois dépendant du comportement défini le type réel et le type réel sur le site d'appel. Les deux sont tout simplement des méthodes / opérateurs qui peuvent être remplacés sur n'importe quel type et compte tenu de tout comportement de l'auteur le désire. Dans mon expérience, je trouve que c'est commun pour les gens à mettre en œuvre .Est égal à un objet, mais de la négligence à mettre en œuvre l'opérateur ==. Cela signifie que .Est égal permettra de réellement mesurer l'égalité des valeurs, tout en == permettront de mesurer si oui ou non ils sont de la même référence.

Quand je travaille avec un nouveau type dont la définition est dans le flux ou l'écriture des algorithmes génériques, je trouve que la meilleure pratique est la suivante

  • Si je veux comparer les références en C#, j'ai utiliser l'Objet.ReferenceEquals directement (pas nécessaire dans le cas générique)
  • Si je veux comparer des valeurs-je utiliser EqualityComparer<T>.Default

Dans certains cas, quand je sens que l'utilisation de l' == est ambigu, je vais utiliser explicitement l'Objet.De référence est égal au code de lever l'ambiguïté.

Eric Lippert a récemment fait un post de blog sur le sujet de pourquoi il y a 2 méthodes de l'égalité dans la CLR. Il vaut la peine de le lire

20voto

Colonel Panic Points 18390

Premièrement, il y a une différence. Pour les nombres

 > 2 == 2.0
True

> 2.Equals(2.0)
False
 

Et pour les cordes

 > string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException
 

Dans les deux cas, == se comporte plus utilement que .Equals

15voto

MikeKulls Points 1498

J'ajouterais que si vous jetez votre objet sur une chaîne, cela fonctionnera correctement. C'est pourquoi le compilateur vous donnera un avertissement disant "Comparaison possible de références involontaires, pour obtenir une comparaison de valeurs, lancez le côté gauche pour taper" chaîne ""

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X