Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Analyse des Beispielcodes von „==" und Equals in C#

Eine kurze Analyse des Beispielcodes von „==" und Equals in C#

黄舟
黄舟Original
2017-03-09 15:43:551116Durchsuche

Die meisten Internetnutzer haben „==“ und „Gleich“ so zusammengefasst:

  1. „==“ vergleicht die Werte zweier Variablen auf Gleichheit.

  2. 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?

2. Was ist eine Überlastung des Bedieners?

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.

3. Umschreiben von Equals

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.

4. Warum brauchen wir Equals, wenn wir „==“ haben?

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.

5. Welche Beziehung besteht zwischen „==“ und „Gleich“?

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn