Quelle est la différence entre .Equals et ==

Quelle est la différence entre a.Equals(b) et a == b pour les types de valeur, les types de référence et les chaînes? Il semblerait qu’un == b fonctionne très bien pour les chaînes, mais j’essaie de m’assurer de bonnes pratiques de codage.

De quand dois-je utiliser Equals et quand devrais-je utiliser == :

La méthode Equals est juste une méthode virtuelle définie dans System.Object et remplacée par les classes qui le font. L’opérateur == est un opérateur qui peut être surchargé par des classes, mais qui a généralement un comportement d’identité.

Pour les types de référence où == n’a pas été surchargé, il compare si deux références font référence au même object – ce qui est exactement ce que l’implémentation de Equals fait dans System.Object.

Les types de valeur ne fournissent pas une surcharge pour == par défaut. Cependant, la plupart des types de valeur fournis par l’infrastructure fournissent leur propre surcharge. L’implémentation par défaut d’Equals pour un type de valeur est fournie par ValueType et utilise la reflection pour effectuer la comparaison, ce qui la rend nettement plus lente qu’une implémentation spécifique à un type. Cette implémentation appelle également Equals sur des paires de références dans les deux valeurs comparées.

 using System; public class Test { static void Main() { // Create two equal but distinct ssortingngs ssortingng a = new ssortingng(new char[] {'h', 'e', 'l', 'l', 'o'}); ssortingng b = new ssortingng(new char[] {'h', 'e', 'l', 'l', 'o'}); Console.WriteLine (a==b); Console.WriteLine (a.Equals(b)); // Now let's see what happens with the same tests but // with variables of type object object c = a; object d = b; Console.WriteLine (c==d); Console.WriteLine (c.Equals(d)); } } 

Le résultat de ce programme court est

 True True False True 

Voici un excellent article de blog sur WHY les implémentations sont différentes .

Essentiellement, == sera lié au moment de la compilation en utilisant les types des variables et .Equals sera lié dynamicment à l’exécution.

Dans la réponse la plus courte:

== L’opérateur doit vérifier l’identité. (ie: a == b sont ces deux sont le même object?)

.Equals () est de vérifier la valeur. (c.-à-d.: a.Les équations (b) contiennent toutes deux des valeurs identiques?)

À une exception près:
Pour les types de valeur de chaîne et prédéfinis (tels que int , float, etc.),
l’opérateur == répondra pour valeur et non identité. (identique à l’utilisation de .Equals ())

A un niveau simple, la différence est la méthode appelée. La méthode == tentera de lier l’opérateur == si elle est définie pour les types en question. Si aucun == n’est trouvé pour les types de valeur, il effectuera une comparaison de valeur et pour les types de référence, il effectuera une comparaison de référence. Un appel à .Equals effectuera une répartition virtuelle sur la méthode .Equals.

En ce qui concerne les méthodes particulières, tout est dans le code. Les utilisateurs peuvent définir / remplacer ces méthodes et faire tout ce qui leur plaît. Idéalement, cette méthode devrait être équivalente (désolé pour le jeu de mots) et avoir le même résultat mais ce n’est pas toujours le cas.

L’une des différences significatives est que == est un opérateur binary statique qui fonctionne sur deux instances d’un type, alors que Equals est une méthode d’instance. La raison en est que vous pouvez le faire:

 Foo foo = new Foo() Foo foo2 = null; foo2 == foo; 

Mais vous ne pouvez pas le faire sans lancer une NullReferenceException :

 Foo foo = new Foo() Foo foo2 = null; foo2.Equals(foo); 

Un moyen simple de vous rappeler la différence est que a.Equals(b) est plus analogue à
a == (object)b .

La méthode .Equals() n’est pas générique et accepte un argument de type “object”. Par conséquent, lorsque vous comparez à l’opérateur ==, vous devez y penser comme si l’opérande de droite avait été converti en object.

Une implication est que a.Equals(b) retournera presque toujours une valeur pour a et b , quel que soit le type (la manière normale de surcharger est de simplement retourner false si b est un type inconnu). a == b va simplement lancer une exception s’il n’y a pas de comparaison disponible pour ces types.

== ” est un opérateur qui peut être surchargé pour effectuer différentes opérations en fonction des types comparés.

L’opération par défaut effectuée par ” == ” est a.Equals(b);

Voici comment vous pouvez surcharger cet opérateur pour les types de chaîne:

 public static bool operator == (ssortingng str1, ssortingng str2) { return (str1.Length == str2.Length;) } 

Notez que ceci est différent de str1.Equals(str2);

Les classes dérivées peuvent également remplacer et redéfinir Equals() .

En ce qui concerne les “meilleures pratiques”, cela dépend de vos intentions.

Pour les chaînes, vous devez faire attention aux comparaisons spécifiques à la culture. L’exemple classique est le double allemand, qui ressemble un peu à un b. Cela devrait correspondre à “ss” mais pas à une simple comparaison ==.

Pour les comparaisons de chaînes qui sont sensibles à la culture, utilisez: Ssortingng.Compare (attendu, valeur, SsortingngComparison ….) == 0? avec la surcharge SsortingngComparison dont vous avez besoin.

Par défaut, les deux == et .Equals() sont équivalents, à part la possibilité d’appeler .Equals() sur une instance null (ce qui vous donnerait une NullReferenceException ). Vous pouvez, cependant, ignorer les fonctionnalités de l’un ou de l’autre (bien que je ne sois pas sûr que ce soit une bonne idée, sauf si vous essayez de contourner les défauts d’un autre système), ce qui signifierait que vous pourriez les faire différemment. .

Vous trouverez des personnes des deux côtés de l’allée quant à celle à utiliser. Je préfère l’opérateur plutôt que la fonction.

Si vous parlez de chaînes, il est toutefois préférable d’utiliser ssortingng.Compare() au lieu de l’une de ces options.