Pourquoi utiliseriez-vous Ssortingng.Equals sur ==?

J’ai récemment Ssortingng.Equals() une base de code volumineuse et j’ai remarqué que toutes les comparaisons de chaînes étaient effectuées à l’aide de Ssortingng.Equals() au lieu de ==

Quelle est la raison de cela, pensez-vous?

Il est fort probable qu’une grande partie de la base de développement provienne d’un arrière-plan Java où l’utilisation de == pour comparer des chaînes est incorrecte et ne fonctionne pas.

En C #, il n’y a pas de différence (pratique) (pour les chaînes) tant qu’elles sont saisies en tant que chaîne.

S’ils sont typés en tant object ou T alors voyez d’autres réponses qui parlent de méthodes génériques ou de surcharge d’opérateur, car vous voulez certainement utiliser la méthode Equals.

Il y a une différence pratique entre ssortingng.Equals et ==

 bool result = false; object obj = "Ssortingng"; ssortingng str2 = "Ssortingng"; ssortingng str3 = typeof(ssortingng).Name; ssortingng str4 = "Ssortingng"; object obj2 = str3; // Comparision between object obj and ssortingng str2 -- Com 1 result = ssortingng.Equals(obj, str2);// true result = Ssortingng.ReferenceEquals(obj, str2); // true result = (obj == str2);// true // Comparision between object obj and ssortingng str3 -- Com 2 result = ssortingng.Equals(obj, str3);// true result = Ssortingng.ReferenceEquals(obj, str3); // false result = (obj == str3);// false // Comparision between object obj and ssortingng str4 -- Com 3 result = ssortingng.Equals(obj, str4);// true result = Ssortingng.ReferenceEquals(obj, str4); // true result = (obj == str4);// true // Comparision between ssortingng str2 and ssortingng str3 -- Com 4 result = ssortingng.Equals(str2, str3);// true result = Ssortingng.ReferenceEquals(str2, str3); // false result = (str2 == str3);// true // Comparision between ssortingng str2 and ssortingng str4 -- Com 5 result = ssortingng.Equals(str2, str4);// true result = Ssortingng.ReferenceEquals(str2, str4); // true result = (str2 == str4);// true // Comparision between ssortingng str3 and ssortingng str4 -- Com 6 result = ssortingng.Equals(str3, str4);// true result = Ssortingng.ReferenceEquals(str3, str4); // false result = (str3 == str4);// true // Comparision between object obj and object obj2 -- Com 7 result = Ssortingng.Equals(obj, obj2);// true result = Ssortingng.ReferenceEquals(obj, obj2); // false result = (obj == obj2);// false 

Ajout de la montre

 obj "Ssortingng" {1#} object {ssortingng} str2 "Ssortingng" {1#} ssortingng str3 "Ssortingng" {5#} ssortingng str4 "Ssortingng" {1#} ssortingng obj2 "Ssortingng" {5#} object {ssortingng} 

Regardez maintenant {1#} et {5#}

obj2 références obj , str2 , str4 et obj2 sont les mêmes.

obj et obj2 sont le object type et d’autres sont ssortingng type

Conclusion :

  1. com1 : resultat = (obj == str2); // true
    • compare l’ object et la ssortingng effectue ainsi un contrôle d’égalité de référence
    • obj et str2 pointent vers la même référence afin que le résultat soit vrai
  2. com2 : resultat = (obj == str3); // false
    • compare l’ object et la ssortingng effectue ainsi un contrôle d’égalité de référence
    • obj et str3 pointent vers les différentes références afin que le résultat soit faux
  3. com3 : resultat = (obj == str4); // true
    • compare l’ object et la ssortingng effectue ainsi un contrôle d’égalité de référence
    • obj et str4 pointent vers la même référence afin que le résultat soit vrai
  4. com4 : resultat = (str2 == str3); // vrai
    • compare la ssortingng et la ssortingng afin d’effectuer une vérification de la valeur de chaîne
    • str2 et str3 sont tous deux “Ssortingng” donc le résultat est vrai
  5. com5 : resultat = (str2 == str4); // vrai
    • compare la ssortingng et la ssortingng afin d’effectuer une vérification de la valeur de chaîne
    • str2 et str4 sont tous deux “Ssortingng” donc le résultat est vrai
  6. com6 : resultat = (str3 == str4); // true
    • compare la ssortingng et la ssortingng afin d’effectuer une vérification de la valeur de chaîne
    • str3 et str4 sont tous deux “Ssortingng” donc le résultat est vrai
  7. com7 : result = (obj == obj2); // false – compare l’ object et l’ object effectue donc une vérification d’égalité de référence – obj et obj2 pointent vers les différentes références, le résultat est donc faux

Il existe une différence subtile mais très importante entre les méthodes == et les méthodes Ssortingng.Equals:

 class Program { static void Main(ssortingng[] args) { CheckEquality("a", "a"); Console.WriteLine("----------"); CheckEquality("a", "ba".Subssortingng(1)); } static void CheckEquality(T value1, T value2) where T : class { Console.WriteLine("value1: {0}", value1); Console.WriteLine("value2: {0}", value2); Console.WriteLine("value1 == value2: {0}", value1 == value2); Console.WriteLine("value1.Equals(value2): {0}", value1.Equals(value2)); if (typeof(T).IsEquivalentTo(typeof(ssortingng))) { ssortingng ssortingng1 = (ssortingng)(object)value1; ssortingng ssortingng2 = (ssortingng)(object)value2; Console.WriteLine("ssortingng1 == ssortingng2: {0}", ssortingng1 == ssortingng2); } } } 

Produit cette sortie:

 value1: a value2: a value1 == value2: True value1.Equals(value2): True ssortingng1 == ssortingng2: True ---------- value1: a value2: a value1 == value2: False value1.Equals(value2): True ssortingng1 == ssortingng2: True 

Vous pouvez voir que l’opérateur == retourne false à deux chaînes de toute évidence égales. Pourquoi? Parce que l’opérateur == utilisé dans la méthode générique est résolu comme étant la méthode op_equal définie par System.Object (la seule garantie de T que la méthode a au moment de la compilation), ce qui signifie qu’elle est une égalité de référence plutôt qu’une valeur.

Lorsque vous avez deux valeurs typées System.Ssortingng explicitement, alors == a une sémantique d’égalité des valeurs car le compilateur résout le == à System.Ssortingng.op_equal au lieu de System.Object.op_equal.

Donc, pour le jouer en toute sécurité, j’utilise presque toujours Ssortingng.Equals pour que j’obtienne toujours la sémantique d’égalité des valeurs que je veux.

Et pour éviter les NullReferenceExceptions si l’une des valeurs est null, j’utilise toujours la méthode Ssortingng.Equals statique :

 bool true = Ssortingng.Equals("a", "ba".Subssortingng(1)); 

Ssortingng.Equals offre des surcharges pour gérer les comparaisons de casse et de culture. Si votre code ne les utilise pas, les devs peuvent juste être utilisés pour Java, où (comme dit Matthew), vous devez utiliser la méthode .Equals pour faire des comparaisons de contenu.

Les deux méthodes font la même fonctionnalité – pour comparer les valeurs . Comme il est écrit dans MSDN:

Mais si l’une de vos instances de chaîne est NULL, ces méthodes fonctionnent différemment:

 ssortingng x = null; ssortingng y = "qq"; if (x == y) // returns false MessageBox.Show("true"); else MessageBox.Show("false"); if (x.Equals(y)) // returns System.NullReferenceException: Object reference not set to an instance of an object. - because x is null !!! MessageBox.Show("true"); else MessageBox.Show("false"); 

Il y a un article sur cet article que vous pourriez trouver intéressant, avec des citations de Jon Skeet. Il semble que l’utilisation soit à peu près la même.

Jon Skeet déclare que la performance de l’instance Equals “est légèrement meilleure lorsque les chaînes sont courtes – à mesure que la longueur des chaînes augmente, cette différence devient complètement insignifiante.”

Je veux append qu’il y a une autre différence. C’est lié à ce que Andrew publie.

Il est également lié à un bug TRÈS pénible à trouver dans notre logiciel. Voir l’exemple simplifié suivant (j’ai également omis la vérification de null).

 public const int SPECIAL_NUMBER = 213; public bool IsSpecialNumberEntered(ssortingng numberTextBoxTextValue) { return numberTextBoxTextValue.Equals(SPECIAL_NUMBER) } 

Cela comstackra et retournera toujours false . Alors que ce qui suit donnera une erreur de compilation:

 public const int SPECIAL_NUMBER = 213; public bool IsSpecialNumberEntered(ssortingng numberTextBoxTextValue) { return (numberTextBoxTextValue == SPECIAL_NUMBER); } 

Nous avons dû résoudre un problème similaire lorsque quelqu’un comparait des énumérations de types différents en utilisant Equals . Vous allez relire plusieurs fois avant de vous rendre compte que c’est la cause du bug. Surtout si la définition de SPECIAL_NUMBER n’est pas proche de la zone du problème.

C’est pourquoi je suis vraiment contre l’utilisation d’Egal dans des situations où ce n’est pas nécessaire. Vous perdez un peu de sécurité de type.

Je viens de me cogner la tête contre un mur en essayant de résoudre un bug car je lisais cette page et concluais qu’il n’y avait pas de différence significative dans la pratique alors je posterais ce lien ici au cas où quelqu’un trouverait des résultats différents sur == et égale.

L’object == égalité échoue, mais .Equals réussit. Est-ce que ça a du sens?

 ssortingng a = "x"; ssortingng b = new Ssortingng(new []{'x'}); Console.WriteLine("x == x " + (a == b));//True Console.WriteLine("object x == x " + ((object)a == (object)b));//False Console.WriteLine("x equals x " + (a.Equals(b)));//True Console.WriteLine("object x equals x " + (((object)a).Equals((object)b)));//True