239 votes

Sont string. Equals() et opérateur == vraiment même ?

Sont-ils vraiment même ? Aujourd'hui, je suis tombé sur ce problème. Voici le vidage de la fenêtre exécution :

Ainsi, les deux s et tvi. En-tête contiennent « Catégorie », mais == retourne false et Equals retourne la valeur true.

s est défini comme chaîne, tvi. En-tête est en fait un TreeViewItem.Header de WPF. Alors, pourquoi ils retournent des résultats différents ? J’ai toujours pensé qu’ils étaient interchangeables en c#.

Quelqu'un peut-il expliquer pourquoi il en est ?

368voto

Jon Skeet Points 692016

Deux différences:

  • Equals est polymorphe (c'est à dire qu'elle peut être remplacée, et la mise en œuvre utilisée dépend du temps d'exécution type de l'objet cible), alors que la mise en œuvre de l' == utilisée est déterminée en fonction du moment de la compilation types d'objets:

    // Avoid getting confused by interning
    object x = new StringBuilder("hello").ToString();
    object y = new StringBuilder("hello").ToString();
    if (x.Equals(y)) // Yes
    
    
    // The compiler doesn't know to call ==(string, string) so it generates
    // a reference comparision instead
    if (x == y) // No
    
    
    string xs = (string) x;
    string ys = (string) y;
    
    
    // Now *this* will call ==(string, string), comparing values appropriately
    if (xs == ys) // Yes
    
  • Equals iront bang si vous l'appelez sur null, == ne

    string x = null;
    string y = null;
    
    
    if (x.Equals(y)) // Bang
    
    
    if (x == y) // Yes
    

Notez que vous pouvez éviter ce dernier étant un problème à l'aide d' object.Equals:

if (object.Equals(x, y)) // Fine even if x or y is null

63voto

Jeffrey L Whitledge Points 27574

Les apparentes contradictions qui apparaissent dans la question sont dues au fait que dans un cas, l' Equals fonction est appelée sur un string de l'objet, et dans l'autre cas, l' == opérateur est appelé sur l' System.Object type. string et object mettre en œuvre l'égalité différemment les uns des autres (d'une valeur de vs référence respectivement).

Au-delà de ce fait, n'importe quel type permet de définir == et Equals différemment, donc en général ils ne sont pas interchangeables.

Voici un exemple d'utilisation double (de Joseph Albahari note du §7.9.2 de la spécification du langage C#):

double x = double.NaN;
Console.WriteLine (x == x);         // False
Console.WriteLine (x != x);         // True
Console.WriteLine (x.Equals(x));    // True

Il poursuit en disant que l' double.Equals(double) méthode a été conçue pour fonctionner correctement avec les listes et les dictionnaires. L' == de l'opérateur, d'autre part, a été conçu pour suivre la norme IEEE 754 pour les types à virgule flottante.

Dans le cas spécifique de la détermination de la chaîne d'égalité, de l'industrie est préférable d'utiliser ni == ni string.Equals(string) la plupart du temps. Ces méthodes déterminer si deux chaînes de caractères sont le même caractère, ce qui est rarement le comportement correct. Il est préférable d'utiliser string.Equals(string, StringComparison), ce qui vous permet de spécifier un type particulier de comparaison. En utilisant le bon de comparaison, vous pouvez éviter beaucoup de potentiel (très difficile à diagnostiquer) les bugs.

Voici un exemple:

string one = "Caf\u00e9";        // U+00E9 LATIN SMALL LETTER E WITH ACUTE
string two = "Cafe\u0301";       // U+0301 COMBINING ACUTE ACCENT
Console.WriteLine(one == two);                                          // False
Console.WriteLine(one.Equals(two));                                     // False
Console.WriteLine(one.Equals(two, StringComparison.InvariantCulture));  // True

Les deux chaînes dans cet exemple, le même aspect ("Café"), cela peut être très difficile à déboguer si à l'aide d'un naïf (ordinale) l'égalité.

45voto

palswim Points 4353

C# a deux "est synonyme de" concepts: Equals et ReferenceEquals. Pour la plupart des classes que vous rencontrerez, l' == opérateur utilise l'un ou l'autre (ou les deux), et généralement seuls les tests pour ReferenceEquals lors de la manipulation de types de référence (mais l' string Classe est une instance où C#, on sait déjà comment tester la valeur de l'égalité).

  • Equals comparer les valeurs. (Même si les deux int variables n'existent pas dans le même endroit dans la mémoire, ils peuvent encore contenir la même valeur.)
  • ReferenceEquals compare la référence et retourne si les opérandes pointent vers le même objet en mémoire.

Exemple De Code:

var s1 = new StringBuilder("str");
var s2 = new StringBuilder("str");
StringBuilder sNull = null;

s1.Equals(s2); // True
s1.ReferenceEquals(s2); // False
s1 == s2 // False - testing with ReferenceEquals
s1 == sNull // False
s1.ReferenceEquals(sNull); // False
s1.Equals(sNull); // Nono!  Explode (Exception)

17voto

0xA3 Points 73439

Le `` propriété de la est statiquement typée de type .

C’est pourquoi la donne . Vous pouvez reproduire cela avec l’extrait de code simple suivant :

11voto

James Curran Points 55356

Moments-là c’est pourquoi la bonne Lord(*) nous a donné un réflecteur, qui vous regardez la mise en œuvre.

(*) En fait, c’était un gars nommé Lutz, mais je suis sûr que le bon Dieu a approuvé...

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