Heim > Artikel > Backend-Entwicklung > Eine kurze Analyse des Beispielcodes von „==" und Equals in C#
Die meisten Internetnutzer haben „==“ und „Gleich“ so zusammengefasst:
„==“ vergleicht die Werte zweier Variablen auf Gleichheit.
Equals vergleicht, ob zwei Variablen auf dasselbe Objekt verweisen.
Beispiel: Dieser Artikel und die Beispiele in diesem Artikel als Beispiel.
public class Person { public Person(string name) { this.Name = name; } public string Name { get; set; } } static void Main(string[] args) { string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); Console.WriteLine(a == b); //true Console.WriteLine(a.Equals(b)); //true object g = a; object h = b; Console.WriteLine(g == h); //false Console.WriteLine(g.Equals(h)); //true Person p1 = new Person("jia"); Person p2 = new Person("jia"); Console.WriteLine(p1 == p2); //false Console.WriteLine(p1.Equals(p2)); //false Person p3 = new Person("jia"); Person p4 = p3; Console.WriteLine(p3 == p4); //true Console.WriteLine(p3.Equals(p4)); //true Console.ReadKey(); }
Wenn die obige Schlussfolgerung richtig ist und „==" die Werte zweier Variablen vergleicht, um sie gleich zu machen, dann sollte der folgende Code nicht wahr sein.
Console.WriteLine(a == b); //true
Offensichtlich verweisen die beiden oben genannten Zeichenfolgenvariablen a und b auf zwei verschiedene Objekte, dh die Speicheradressen, die sie im Stapelbereich speichern, sind ebenfalls unterschiedlich. Aber warum sind sie gleich?
Beim Überladen von Operatoren wird ein vorhandener Operator neu definiert und ihm eine andere Funktion zugewiesen, um ihn an verschiedene Datentypen anzupassen. Lassen Sie uns eine einfache Analogie geben: den „+“-Operator, in dem „+“ zwei
Wenn alle Kanten Variablen numerischen Typs sind, stellt der „+“-Operator die mathematische Bedeutung von „+“ dar. Wenn eine Seite des „+“-Operators vom Typ „String“ ist, stellt der „+“-Operator die Verbindung
dar Die Bedeutung der Zeichenfolge. Es gibt viele Beispiele für eine solche Operatorüberladung. Hat das also etwas mit dem Thema dieses Artikels zu tun? Was ich sagen möchte ist, dass die oben genannten String-Variablen: a, b auf die String-Klasse
zurückzuführen sind Überladener Operator „==", siehe folgenden Quellcode:
public static bool operator == (String a, String b) { return String.Equals(a, b); } public static bool operator != (String a, String b) { return !String.Equals(a, b); }
Es ist offensichtlich, dass der Operator „==“ in der String-Klasse wirklich überlastet ist, und zwar nicht nur „==“, sondern auch „!=“. Und rufen Sie direkt die Equals-Methode in der String-Klasse innerhalb der überladenen Operatormethode
auf Der Quellcode lautet wie folgt:
public static bool Equals(String a, String b) { if ((Object)a==(Object)b) { return true; } if ((Object)a==null || (Object)b==null) { return false; } if (a.Length != b.Length) return false; return EqualsHelper(a, b); }
Aus dem oben Gesagten kann geschlossen werden, dass der Operator „==“ nicht unbedingt vergleicht, ob die in zwei Variablen gespeicherten Werte gleich sind. Dies hängt davon ab, ob der aktuelle Operator im aktuellen Typ überladen ist.
Immer noch das obige Beispiel:
string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); Console.WriteLine(a == b); //true Console.WriteLine(a.Equals(b)); //true
Aus dem Obigen ist ersichtlich, dass a und b zwei verschiedene Objekte sind. Wenn Equals jedoch True ist, ist die obige Schlussfolgerung: „Equals vergleicht, ob zwei Variablen auf dasselbe Objekt zeigen“ ungültig. Grund
Schauen Sie sich die Equals-Methode in der String-Klasse an:
public override bool Equals(Object obj) <br> { if (this == null) //this is necessary to guard against reverse-pinvokes and throw new NullReferenceException(); //other callers who do not use the callvirt instruction String str = obj as String; if (str == null) return false; if (Object.ReferenceEquals(this, obj)) return true; if (this.Length != str.Length) return false; return EqualsHelper(this, str); } public bool Equals(String value) <br> { if (this == null) //this is necessary to guard against reverse-pinvokes and throw new NullReferenceException(); //other callers who do not use the callvirt instruction if (value == null) return false; if (Object.ReferenceEquals(this, value)) return true; if (this.Length != value.Length) return false; return EqualsHelper(this, value); }
Wie aus dem Obigen ersichtlich ist, schreibt die String-Klasse nicht nur die Equals in Object neu, sondern verfügt auch über eine eigene Equals-Methode, der Implementierungscode ist jedoch nahezu identisch. Vergleichstyp, Speicheradresse,
Tatsächlicher Wert, um das Endergebnis zu erhalten. Equals ist also nicht unbedingt ein einzelner Vergleich, ob die Referenzadressen gleich sind, ganz zu schweigen davon, dass wir es auch umschreiben und anpassen können. Aber schreiben Sie
um Equals erfordert ebenfalls Aufmerksamkeit. Wenn Sie also HashMap, HashSet und Hashtable verwenden müssen, müssen Sie auch GetHashCode () neu schreiben.
Es gibt ein chinesisches Sprichwort: „Die Existenz von allem muss seinen eigenen Grund und Wert haben.“ Das Gleiche gilt für „==“ und „Gleich“. Die grundlegendste Implementierung von „==" in Referenztypen ist der Vergleich von
Vergleichen Sie, ob die Speicheradressen der beiden Objekte konsistent sind. Wenn sie konsistent sind, sind sie gleich, andernfalls sind sie nicht gleich. Eine solche Implementierung wird offensichtlich aus Hardware-Perspektive gedacht. Wenn zwei Objekte gleich sind, sind sie dasselbe Objekt,
Dann müssen ihre Adressen im Speicher gleich sein. Aber oft hängt das „Verhalten (die Methode)“ von der Perspektive ab, aus der wir die Welt betrachten. Zum Beispiel: String-Typ, wir deklarieren ein Zeichen
Bei Zeichenfolgen geht es mehr um den tatsächlichen Wert der Zeichenfolge als darum, ob die beiden Objekte einmal oder zweimal im Speicher erstellt werden (d. h. ob die Speicheradressen gleich sind), solange sie
haben Wenn die tatsächlichen Werte gleich sind, betrachten wir sie als gleich. Dies wird aus der Geschäftslogik des Lebens und nicht aus einer Maschinenperspektive verstanden. Natürlich die gleiche Zeichenfolge wie oben
Unabhängig davon, ob Variablen einmal oder zweimal erstellt werden, denke ich: „Konstanter Pool (oder String-Detention-Pool)“ hat uns die beste Lösung gegeben.
Der Operator „==“ und „Gleich“ ergänzen sich tatsächlich. Weil: Die Hauptimplementierungsform des „=="-Operators wird aus der „Computerperspektive (oder Hardwareperspektive)" implementiert,
Equals wird auf der Grundlage allgemeiner Geschäftsszenarien oder spezifischer Geschäftsszenarien implementiert. Es besteht kein zwangsläufiger Zusammenhang zwischen beiden. Sie wählen einfach unterschiedliche Methoden entsprechend Ihren eigenen Geschäftsanforderungen.
Equals in Object ist also visuell. Es wurde in vielen Klassen neu geschrieben und erreicht tatsächlich das spezifische Verhalten, das im aktuellen Typ erforderlich ist: Polymorphismus. Es ist also nicht schwer, das oben Gesagte zu erklären:
object g = a; object h = b; Console.WriteLine(g == h); //false Console.WriteLine(g.Equals(h)); //true
Da der überladene Operator „==" nicht in Object implementiert ist, besteht die aktuelle Vergleichsmethode von „==" darin, zu vergleichen, ob die im Stapelbereich der beiden Variablen gespeicherten Speicheradressen gleich sind. Und Gleich ist
Beim Aufruf von Equals in der String-Klasse liegt der Grund darin, dass die g-Variable während des Betriebs tatsächlich auf ein String-Objekt zeigt und der aktuelle Objekttyp nur das Verhalten von Visual Studio und dem Compiler ist, das heißt: er ist immer noch polymorph.
Letztendlich hat alles seine Regeln: „==“ und „Gleich“ sind keine Ausnahme. Für Details klicken Sie bitte auf „Zu MSDN springen“.
Das obige ist der detaillierte Inhalt vonEine kurze Analyse des Beispielcodes von „==" und Equals in C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!