Benutzer mit den meisten Antworten
Strings vergleichen: Was ist besser "==" oder Equals()?

Frage
Antworten
-
Hallo Heiko,
auch wenn es erst trivial aussieht, eine Zeichenkette vergleichen kann relativ komplex werden.
Zunächst zu Equals vs. "==":
Bei Equals muß x im obigen Beispiel ungleich null sein, sonst gibt es eine Ausnahme:string x = null, y = "ábc"; Console.WriteLine("==: {0}", x == y); // fällt auf die Nase: // Console.WriteLine("Equals: {0}", x.Equals(y));
denn nur bei "==", was über den für String überladenen Equals-Operator zu String.Equals(x, y) führt,
wird berücksichtigt, dass der linke Wert null sein kann.Damit ist aber nicht immer getan.
Denn es hängt davon ab, wie Du eine Zeichenkette vergleichen willst.
Bei String.Equals findest Du weitere Überladungen mit StringComparison ,
womit man genauer bestimmen kann, wie Zeichen verglichen werden sollen.
Die Standardmethode, die "==" verwendet, wäre der auf Ordinal Werte.Willst Du Zeichenkette auf Basis ihrer Kultur vergleichen, solltest Du
CurrentCulture oder CurrentCultureIgnoreCase (ohne Groß/Klein) verwenden:(man achte auf das "ß")x = "äöüß"; y = "ÄÖÜss"; Console.WriteLine("Equals: {0}", x.Equals(y)); Console.WriteLine("Equals: {0}", x.Equals(y, StringComparison.CurrentCultureIgnoreCase));
Die StringComparision Option existiert für weitere Methoden, die Vergleiche implizieren, wie Compare uam,
siehe auch: Gewusst wie: Vergleichen von Zeichenfolgen (C#-Programmierhandbuch)Gruß Elmar
- Als Antwort markiert Heiko Adams Montag, 16. August 2010 11:48
Alle Antworten
-
Hallo Heiko,
auch wenn es erst trivial aussieht, eine Zeichenkette vergleichen kann relativ komplex werden.
Zunächst zu Equals vs. "==":
Bei Equals muß x im obigen Beispiel ungleich null sein, sonst gibt es eine Ausnahme:string x = null, y = "ábc"; Console.WriteLine("==: {0}", x == y); // fällt auf die Nase: // Console.WriteLine("Equals: {0}", x.Equals(y));
denn nur bei "==", was über den für String überladenen Equals-Operator zu String.Equals(x, y) führt,
wird berücksichtigt, dass der linke Wert null sein kann.Damit ist aber nicht immer getan.
Denn es hängt davon ab, wie Du eine Zeichenkette vergleichen willst.
Bei String.Equals findest Du weitere Überladungen mit StringComparison ,
womit man genauer bestimmen kann, wie Zeichen verglichen werden sollen.
Die Standardmethode, die "==" verwendet, wäre der auf Ordinal Werte.Willst Du Zeichenkette auf Basis ihrer Kultur vergleichen, solltest Du
CurrentCulture oder CurrentCultureIgnoreCase (ohne Groß/Klein) verwenden:(man achte auf das "ß")x = "äöüß"; y = "ÄÖÜss"; Console.WriteLine("Equals: {0}", x.Equals(y)); Console.WriteLine("Equals: {0}", x.Equals(y, StringComparison.CurrentCultureIgnoreCase));
Die StringComparision Option existiert für weitere Methoden, die Vergleiche implizieren, wie Compare uam,
siehe auch: Gewusst wie: Vergleichen von Zeichenfolgen (C#-Programmierhandbuch)Gruß Elmar
- Als Antwort markiert Heiko Adams Montag, 16. August 2010 11:48
-
Hallo Heiko,
Du schriebst: Mit anderen Worten: x==y ist nur sowas wie ein Alias für x.Equals(y)
Elmar schrieb: Ja, wenn x != null.
Ich möchte noch einmal zum "allgemeinen" Aspekt eines Vergleiches "==" zu "Equals" kommen - also nicht bzgl. Deiner doch explizit nach Strings gestellten Frage (also im Prinzip außer der Reihe).
Bei Strings ist der Fall wegen des Referenz-Typs sehr einfach.
Im Allgemeinen gilt die Aussage [x==y ist nur sowas wie ein Alias für x.Equals(y)] aber nicht!
Auch nicht, "wenn x != null". Beachte dazu folgendes Beispiel:int i = 5; int j = 5;
bool resultGleich = (i == j); //true
bool resultEquals = (i.Equals(j)); //trueobject o1 = 5; object o2 = 5;
bool resultGleich2 = (o1 == o2); // false!
bool resultEquals2 = (o1.Equals(o2)); // trueHier eine gute Beschreibung, was Equals im Gegensatz zu "==" leisten muss:
[Object.Equals-Methode (Object) (System)]
http://msdn.microsoft.com/de-de/library/bsc2ak47.aspx
Für solche Prüfungen nutzt man i.A. Equals für Wertprüfungen bei object-Typen.
Für Referenz-Prüfungen gibt es auch ReferenceEquals.
Es gibt also im Allgemeinen recht unterschiedliche und auch überschreibbare
(Equals ist ja beim Typ object: virtual) Gleichheits-Semantiken.
ciao Frank -
Hallo Heiko,
der "==" führt einen Referenzvergleich durch (Verweise auf die gleicher Speicheradresse?). Da .net Stringobjekte poolt, haben zwei gleiche Zeichenketten in der Regel auch die gleiche Speicheradresse. Equals prüft, ob beide Stringobjeke inhaltsgleich sind (ob der gleiche Text drinsteht).
Viele Grüße
Holger M. Rößler
-
Hallo Holger,
im Falle von Zeichenketten (System.String) gilt das so nicht, dort ist der Gleichheitsoperator überladen.
Auch wenn System.String ein Referenztyp ist, so hat er eine Wertsemantik (wie bei Object.Equals erläutert).
Und so wird bei Zeichenketten der Inhalt verglichen.Gleiche Speicheradressen haben Zeichenketten nicht zwangsläufig.
Zwar werden Konstanten üblicherweise zusammengefaßt und erhalten so die gleiche Adressen.
Wird eine Zeichenkette zur Laufzeit erstellt, so wird sie unterschiedliche Verweise haben.
Ein "Pooling" kann durch String.Intern erreicht werden, siehe aber "Überlegungen zur Leistung" dort.Gruß Elmarstring x = "abc"; string y = "a" + "b" + "c"; // vom Compiler zusammengesetzt Console.WriteLine("{0} == {1}: {2}, ReferenceEquals: {3}", x, y, x == y, object.ReferenceEquals(x, y)); x += "d"; y += "d"; Console.WriteLine("{0} == {1}: {2}, ReferenceEquals: {3}", x, y, x == y, object.ReferenceEquals(x, y)); // Intern x = String.Intern(x); y = String.Intern(y); Console.WriteLine("{0} == {1}: {2}, ReferenceEquals: {3}", x, y, x == y, object.ReferenceEquals(x, y));
-
Hi Elmar,
oooops. Dann hätte ich ja fast unwahrheit verbreitet. Aber so ist es mir damals im Studium gelehrt worden. Naja, vielen Dank für den Hinweis an dich und ein big sorry an Heiko dafür, dass ich Käse erzählt habe.
Vielen Dank und viele Grüße
Holger M. Rößler