C# Unterschied zwischen == und Equals()
Ich habe eine Bedingung in einer silverlight-Anwendung, vergleicht 2 strings, aus irgendeinem Grund, wenn ich ==
es gibt false während .Equals()
gibt wahr.
Hier ist der code:
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
//Execute code
}
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
//Execute code
}
Irgendeinem Grund, warum dies passiert ist?
Siehe auch: stackoverflow.com/questions/144530/or-equals
String überschreibt
Erweitern @DrewNoakes' Bemerkung: Der compiler wählt eine
Erklärung ist präzise. Es sollte angemerkt werden, dass, wenn die linke Seite des
für die Ratschläge zu Lesen, dass der compiler Warnungen. Noch besser: schalten Sie die Warnungen-wie-Fehler-option um zu erzwingen, dass jeder Aufmerksamkeit auf Sie zu bezahlen.
String überschreibt
==
, aber die Betreiber sind nicht polymorph. In diesem code, der ==
operator aufgerufen wird geben Sie object
, die Identität-Vergleich statt einem Wert eine.Erweitern @DrewNoakes' Bemerkung: Der compiler wählt eine
==
überlastung basierend auf der compile-Zeit-Typ der Operanden. Die Content
Eigenschaft ist object
. Die Betreiber sind nicht virtuell, so dass die default-Implementierung von ==
genannt, was einen Verweis Geschlechter-Vergleich. Mit ist Gleich der Aufruf der virtuellen Methode object.Equals(object)
; string
überschreibt diese Methode und führt einen ordinalvergleich auf den string-Inhalt. Siehe msdn.microsoft.com/en-us/library/fkfd9eh8(v=vs. 110).aspx und referencesource.microsoft.com/#mscorlib/system/string.cs,507.Erklärung ist präzise. Es sollte angemerkt werden, dass, wenn die linke Seite des
==
hat compile-Zeit-Typ object
und der rechten Seite hat compile-Zeit-Typ string
, dann den C# - compiler Holen müssen (problematisch, in diesem Fall) überlast -operator ==(object, object)
; aber es Problem während der Kompilierung eine Warnung, dass es sein könnte, ungewollt. So ist Lesen die compile-Zeit-Warnungen! Um das Problem zu lösen und trotzdem ==
, warf der linken Seite, um string
. Wenn ich mich richtig erinnere, den text der Warnung schlägt vor, dass nur.für die Ratschläge zu Lesen, dass der compiler Warnungen. Noch besser: schalten Sie die Warnungen-wie-Fehler-option um zu erzwingen, dass jeder Aufmerksamkeit auf Sie zu bezahlen.
InformationsquelleAutor Drahcir | 2009-05-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn
==
verwendet wird, auf einem Ausdruck vom Typobject
werde es beheben zuSystem.Objekt.ReferenceEquals
.die
Equals
ist nur einvirtual
Methode und verhält sich als solche, also die überschriebene version verwendet (also die, fürstring
Typ vergleicht den Inhalt).Das ist nicht wahr. Auch wenn == ist in der Klasse implementiert wird ignoriert, weil der Typ auf der linken Seite des Vergleichs Objekt. Es sieht aus wie operatorüberladungen sind bestimmt zur compile-Zeit und zur compile-Zeit, er weiß, dass auf der linken Seite ist ein Objekt.
Ich glaube, dass Ihre erste Aussage ist richtig, dass == die aufgelöst wird, zu widersprechen, aber deine zweite Aussage, dass operator-überladungen lösen, in einer ähnlichen Art und Weise ist nicht. Sie sind ganz anders, die ist, warum .Gleich wird aufgelöst string, während == aufgelöst wird, zu widersprechen.
Um klar zu sein,
object
- Typ (beachten Sie die monospace-Schrift) ist technisch gemeint sein "ein Ausdruck vom TypSystem.Object
". Es hat nichts zu tun mit der laufzeittyp der Instanz, die bezeichnet wird durch den Ausdruck. Ich denke, die Aussage "benutzerdefinierte Operatoren behandelt werden, wievirtual
Methoden" ist extrem irreführend. Sie werden behandelt, wie überladene Methoden und nur von der compile-Zeit-Typ der Operanden. In der Tat, nach dem Satz von Kandidaten benutzerdefinierte Operatoren berechnet, der rest der binding-Prozedur wird genau die Methode überlast Auflösung AlgorithmusDas irreführende daran ist, dass
virtual
Methode Auflösung hängt von der tatsächlichen Laufzeit-Typ eines einer Instanz, in der Erwägung, dass, der ganz, ignoriert operator überladen Auflösung, und das ist in der Tat der springende Punkt meiner Antwort.InformationsquelleAutor Mehrdad Afshari
Beim Vergleich von ein-Objekt-Referenz in einen string (auch wenn die Objekt-Referenz bezieht sich auf eine Zeichenfolge), das spezielle Verhalten der
==
Betreiber der string-Klasse wird ignoriert.Normalerweise (wenn nicht der Umgang mit strings, das ist),
Equals
vergleicht Werte, während==
vergleicht Objekt-Referenzen.Wenn zwei Objekte, die Sie vergleichen sind bezogen auf die gleiche Instanz eines Objektes, dann wird true zurückgegeben, aber wenn man den gleichen Inhalt hat, und kam aus einer anderen Quelle (ist eine separate Instanz mit den gleichen Daten), nur Entspricht, wird true zurückgegeben. Jedoch, wie bereits angemerkt in den Kommentaren, string ist ein Sonderfall, da es überschreibt die
==
- operator, so dass, wenn der Umgang ausschließlich mit string-Referenzen (und nicht Objekt-Referenzen), werden nur die Werte verglichen werden, auch wenn Sie separate Instanzen. Der folgende code veranschaulicht die feinen Unterschiede im Verhalten:Ausgabe:
Ich lasse den post hier, weil ich denke, es ist wertvoll zu betonen, was die nicht passiert, da muss man gut aufpassen, um es zu realisieren. (Und ich denke, der code zu zeigen den richtigen und falschen Absprachen lohnt sich auch.) Ich hoffe, dass die Bewertung gehen nicht unter 0.
Sicherlich String implementiert einen benutzerdefinierten = = - operator. Wenn es nicht dann mit == würde nicht vergleichen Sie den Inhalt. Also String ist ein schlechtes Beispiel hier zu verwenden, da es nicht helfen uns zu verstehen, den Allgemeinen Fall, wo keine benutzerdefinierten operator definiert wurde.
+1 für die epic-code-Beispiel, dass mir den Sinn dieses. Zeigt den Allgemeinen Fall der statischen Art(Links-Hand-Seite Typ) Objekt-und dem speziellen Fall, dass der statische Typ(/RHS-Typ) als string. Und berührt auch auf string-ein Praktikum.
Wenn mehrere string-Literale sind identisch, der compiler ist intelligent genug, um zu verwenden Sie die gleiche Adresse für die beiden Verweise, da strings in .NET unveränderlich sind.
InformationsquelleAutor BlueMonkMN
==
und.Equals
sind sowohl abhängig vom Verhalten definiert, der tatsächliche Typ und die tatsächliche Typ an der call-site. Beide sind nur von Methoden /Operatoren, die überschrieben werden können, auf irgendeine Art und irgendwelche Verhalten der Autor dies wünscht. In meiner Erfahrung, ich finde es ist üblich, für Menschen zu implementieren.Equals
auf ein Objekt, aber Vernachlässigung zu implementieren Betreiber==
. Dies bedeutet, dass.Equals
wird tatsächlich zu Messen, die Gleichheit der Werte während==
wird festgestellt, ob oder nicht Sie sind, die die gleiche Referenz.Wenn ich arbeiten bin mit einer neuen Art, deren definition im Fluss oder generische algorithmen schreiben, ich finde die beste übung ist die folgende
Object.ReferenceEquals
direkt (nicht erforderlich im Allgemeinen Fall)EqualityComparer<T>.Default
In einigen Fällen, wenn ich fühle die Verwendung von
==
mehrdeutig ist, werde ich explizitObject.Reference
gleich in den code zu entfernen, der Mehrdeutigkeit.Eric Lippert habe vor kurzem einen blog-post zum Thema warum gibt es 2 Methoden der Geschlechter in der CLR. Es lohnt sich das Lesen
Ich sollte wirklich gesagt haben: "wenn ich nicht mit einem Typ, ich finde die beste übung ist die folgende". Ja, VB hat viel bessere Semantik, weil hier wirklich trennt, Wert-und Referenz-Gleichheit. C# mischt die beiden zusammen und es verursacht gelegentlich Mehrdeutigkeit Fehler.
Das ist nicht ganz richtig. == kann nicht überschrieben werden, es ist eine statische Methode. Es kann nur dann überladen werden, das ist ein wichtiger Unterschied. Also der code, der ausgeführt wird, für a = = - operator verbunden ist zur compile-Zeit, während Gleich virtuell ist und fand zum Zeitpunkt der Ausführung.
InformationsquelleAutor JaredPar
Erstens, es ist einen Unterschied. Für zahlen
Und für Streicher
In beiden Fällen
==
verhält sinnvoller als.Equals
==
Betreiber eine gute Sache. Zum Beispiel, sollten 16777216.0 f gleich (int)16777217, (Doppel -) 16777217.0, beides oder keines von beiden? Vergleiche zwischen integralen Typen sind in Ordnung, aber Gleitkomma-Vergleiche sollten nur durchgeführt werden, IMHO sind die Werte explizit umgewandelt werden, um matching-Typen. Der Vergleich derfloat
auf etwas anderes als einfloat
oder einedouble
auf etwas anderes als eindouble
, erscheint mir als ein wichtiger code, der Geruch sollte nicht kompilieren, ohne Diagnose.Ich Stimme zu—es ist erschütternd, dass
x == y
bedeutet nichtx/3 == y/3
(versuchenx = 5
undy = 5.0
).Ich halte die Verwendung von
/
für integer division auf einen Mangel in der Konstruktion von C# und Java. Pascaldiv
und sogar VB.NET's` are much better. The problems with
==` schlechter, aber:x==y
undy==z
bedeutet nicht, dassx==z
(betrachten Sie die drei zahlen in meinem vorherigen Kommentar). Als auch für die Beziehung, die Sie vorschlagen, auch wennx
undy
sind beidefloat
oder beidedouble
,x.equals((Object)y)
bedeutet nicht, dass1.0f/x ==
1.0 f/y` (wenn ich meine druthers, es würde garantieren, dass, auch wenn==
nicht unterscheiden positive und nullEquals
sollte).Das ist normal, da Equals()'s der erste parameter ist ein string!
InformationsquelleAutor Colonel Panic
Ich würde hinzufügen, dass, wenn Sie werfen Sie Ihre Objekt in einen string, dann wird es korrekt funktionieren. Dies ist der Grund, warum der compiler wird Ihnen eine Warnung sagen:
object expr = XXX; if (expr == "Energy") { ... }
da die linke Seite von compile-time-Typobject
, die compiler verwenden muss, um die überlastungoperator ==(object, object)
. Es prüft, ob Referenz-Gleichheit. Ob das gebentrue
oderfalse
kann schwer vorhergesagt werden, da der string Praktikum. Wenn Sie wissen die linke Seite ist entwedernull
oder der Typstring
, warf der linken Seite, umstring
vor der Verwendung==
.zu stellen, dass ein anderer Weg. == (in der Bestimmung, ob es verwendet Referenz-Gleichheit oder der Wert der Geschlechter) ist abhängig vom compile-Zeit-Typ/statischer Typ/Links type. (das ist der Typ, aufgelöst in einer compile-Zeit-Analyse). Anstatt die runtime-Typ-dynamischer Typ/RHS-Typ. BlueMonkMN code zeigt, dass, obwohl nicht mit dem Gießen.
InformationsquelleAutor MikeKulls
= = - Operator
1. Wenn Operanden Wert-Typen und Ihre Werte gleich sind, es gibt true zurück, sonst false.
2. Wenn Operanden Referenz-Typen mit Ausnahme von string und beziehen sich beide auf dasselbe Objekt, es gibt true zurück, sonst false.
3. Wenn die Operanden sind vom Typ string und die Werte sind gleich, es gibt true zurück, sonst false.
.Gleich
1. Wenn die Operanden sind Referenz-Typen, es führt Referenz-Gleichheit, wenn beide verweisen auf dasselbe Objekt, es gibt true zurück, sonst false.
2. Wenn die Operanden sind Value-Typen, die dann im Gegensatz zu den = = - operator überprüft die nach Ihrer Art erste und, Wenn Ihre Typen denselben führt es = = - operator andernfalls gibt Sie false zurück.
==
- operator können überladen werden, für jede Art, nicht nur string. Beschreibt einen Sonderfall Ausnahme nur für string-verfälscht die Betreiber der Semantik. Es wäre genauer, wenn auch vielleicht nicht sonderlich hilfreich, zu sagen "wenn die Operanden sind Referenz-Typen es gibt true zurück, wenn die Operanden auf das gleiche Objekt beziehen, es sei denn, es ist eine anwendbare überlastung, in welchem Fall die Umsetzung, die überlastung bestimmt das Ergebnis". Das gleiche gilt fürEquals
mit der zusätzlichen Komplikation, dass es sich um eine virtuelle Methode, so dass Ihr Verhalten außer Kraft gesetzt werden können, sowie überlastet.InformationsquelleAutor kashif
Soweit ich es verstehe, die Antwort ist einfach:
Ich hoffe, dass ich richtig bin und dass es Ihre Frage beantwortet.
InformationsquelleAutor Liraz Shaka Amir
Da die statische version der
.Equal
Methode nicht erwähnt wurde bisher, möchte ich hinzufügen, diese hier zusammenzufassen und zu vergleichen, die 3 Variationen.wo
MyString
ist eine variable, die kommt von woanders im code.Hintergrund-info und zum summerize:
In Java
==
um Zeichenketten miteinander zu vergleichen, sollten nicht verwendet werden. Ich erwähne dies für den Fall, Sie brauchen, um zu verwenden, die beide Sprachen und auchSie wissen lassen, dass mit
==
kann auch ersetzt werden durch etwas besseres in C#.In C# gibt es keinen praktischen Unterschied für den Vergleich von strings mithilfe von Methode 1 oder Methode 2, solange beide vom Typ string sind. Jedoch, wenn man null, ist von einem anderen Typ (wie integer), oder man stellt ein Objekt dar, das eine andere Referenz, dann, wie die erste Frage zeigt, können Sie erleben, dass der Vergleich der Inhalte für die Gleichstellung darf nicht zurückgeben, was Sie erwarten.
Lösungsvorschlag:
Weil mit
==
ist nicht genau das gleiche wie mit.Equals
beim vergleichen von Dingen, die Sie verwenden können, die static String.Gleich - Methode statt. Auf diese Weise, wenn die beiden Seiten nicht die gleiche Art werden Sie noch vergleichen der Inhalte, und wenn der eine null ist, Sie vermeiden die Ausnahme.Es ist ein wenig mehr zu schreiben, aber meiner Meinung nach auch sicherer.
Hier einige Infos kopiert vom Microsoft:
Parameter
a
StringDen ersten string zu vergleichen, oder
null
.b
StringDen zweiten string zu vergleichen, oder
null
.Zurück
Boolean
true
wenn der Wert desa
ist der gleiche wie der Wert vonb
; andernfallsfalse
. Wenn beidea
undb
sindnull
wurde, gibt die Methodetrue
.InformationsquelleAutor levteck
Ich bin ein bisschen verwirrt hier. Wenn die runtime-Typ der Inhalt ist vom Typ string, dann == und Equals sollte true zurückgeben. Da dies jedoch nicht der Fall zu sein, dann runtime-Typ der Inhalt ist nicht als string und ruft Gleich an, Sie tut eine referenzielle Gleichheit, und dies erklärt, warum Equals("Energie-Angriff") schlägt fehl. Jedoch, im zweiten Fall, die Entscheidung auf die überladene == static operator aufgerufen werden soll, erfolgt zur compile-Zeit und diese Entscheidung scheint zu sein, ==(string,string). dies lässt mich vermuten, dass der Inhalt stellt eine implizite Konvertierung zu string.
Standardmäßig wird der operator == testet für Referenz-Gleichheit durch die Bestimmung, ob zwei Referenzen das gleiche Objekt anzugeben. Daher Referenz-Typen nicht zu implementieren operator==, um diese Funktionalität. Wenn ein Typ unveränderbar, das heißt, die Daten, die in der Instanz nicht geändert werden kann, überladen von operator == zu vergleichen mit dem Wert der Gleichheit, statt der Referenz-Gleichheit kann sein nützlich, weil Sie als unveränderliche Objekte sind, können Sie als gleichartig angesehen werden, solange Sie den gleichen Wert haben. Es ist nicht eine gute Idee zu überschreiben operator == in nicht-immutable-Typen.
InformationsquelleAutor Mehmet Aras
Gibt es eine weitere dimension, die zu einer früheren Antwort von @BlueMonkMN. Die zusätzliche dimension ist, dass die Antwort auf die @Drahcir Titel-Frage, wie es angegeben ist, hängt auch davon ab wie kamen wir an der
string
Wert. Zur Veranschaulichung:Ausgabe:
InformationsquelleAutor Novichok
Hinzufügen, ein weiterer Punkt, der die Antwort.
.EqualsTo()
Methode gibt, den Sie bereitstellen, zu vergleichen, gegen die Kultur und die groß-und Kleinschreibung.InformationsquelleAutor Bala
Den
==
token in C# wird verwendet für zwei verschiedene Geschlechter-check-Betreiber. Wenn der compiler trifft auf das token, es wird geprüft, ob entweder der Arten verglichen, umgesetzt hat, eine equality-operator überladen für die jeweilige Kombination-Arten im Vergleich(*), oder für eine Kombination von Arten, auf die beide Arten umgewandelt werden kann. Wenn der compiler findet eine solche überlastung wird, verwenden Sie es. Andernfalls, wenn die beiden Arten sind sowohl in Referenz-Typen, und Sie sind nicht losgelöst von Klassen (entweder kann eine Schnittstelle, oder Sie kann bezogen werden Klassen), wird der compiler Bezug==
als Referenz-Vergleichsoperator. Wenn weder Bedingung gilt, Kompilierung wird fehlschlagen.Beachten Sie, dass einige andere Sprachen verwenden Sie separate Token für die zwei-Geschlechter-check-Betreiber. In VB.NET zum Beispiel, die
=
token wird in Ausdrücken verwendet, die ausschließlich für den overloadable Geschlechter-check-operator, undIs
ist die Referenz-test-oder null-test-operator. Eine Verwendung=
auf eine Art, die nicht überschreiben die Geschlechter-check-operator fehl, so wird versuchtIs
für andere Zwecke als Test-Referenz-Gleichheit oder der Nichtigkeit.(*)- Typen in der Regel nur überlastung der Geschlechter für den Vergleich mit sich selbst, aber es kann nützlich sein, für die Arten, um eine überlastung der Gleichheits-operator für den Vergleich mit anderen bestimmten Typen; beispielsweise
int
haben könnte (und IMHO sollte aber nicht) definiert, die einer Gleichheit der Operatoren für den Vergleich mitfloat
, so dass 16777217 nicht melden Sie sich gleich 16777216f. Wie es ist, da kein solcher operator definiert ist, C# wird die Förderung derint
zufloat
, Runden auf 16777216f vor der Gleichheit-check-operator sieht, dass Betreiber sieht dann zwei gleiche floating-point-zahlen und Berichte, die Sie als gleich, nichts von der Rundung, die stattgefunden hat.3
als gleich3.0f
. Wenn wir verlangen, dass der Programmierer zu sagen, was vorgesehen ist in jedem Fall, dann gibt es keine Gefahr in Verzug Verhalten führt zu unerwünschten Ergebnissen führen, da es kein Standard-Verhalten.Mein persönliches Gefühl ist, dass die Sprachen haben sollten, Ihre "normalen" Mittel der Gleichheit Tests implementiert eine äquivalenz-relation, und bewahre alle Kombinationen von Operanden, für die wäre es nicht. Ich sehe nicht ein riesiger Vorteil, dass eine Sprache überprüfen Gleichheit zwischen Ganzzahlen und Fließkommazahlen durch die Bestätigung, dass ein float repräsentiert genau eine ganze Zahl, entspricht der int-Vergleich einfach verbieten solche Vergleiche, aber würde überlegen, entweder Konzept überlegen, um mit der Sprache durchführen einer verlustbehafteten Umwandlung vor dem Vergleich.
InformationsquelleAutor supercat
Wirklich Super Antworten und Beispiele!!!
Möchte ich nur hinzufügen, der grundlegende Unterschied zwischen den beiden,
Mit diesem Konzept im Hinterkopf, wenn Sie aus der Arbeit beliebiges Beispiel (suchen Sie in der linken hand und rechten hand-Typ der Referenz, und überprüfen/zu wissen, ob der Typ tatsächlich hat der = = - operator überladen und Equals wird überschrieben), Sie sind sicher zu bekommen die richtige Antwort.
InformationsquelleAutor Manish Basantani
Nur als Ergänzung zu den bereits guten Antworten: Dieses Verhalten ist NICHT beschränkt auf die Saiten oder das vergleichen verschiedener numbertypes. Auch wenn beide Elemente sind vom Typ object mit dem gleichen zugrunde liegenden Typ. "==" funktioniert nicht.
Folgende Abbildung zeigt die Ergebnisse des Vergleichs von zwei object {int} - Werte
InformationsquelleAutor Ole Albers
Wenn wir es schaffen, jedes Objekt gibt es zwei Teile zu dem Objekt, ist der Inhalt und das andere ist der Verweis auf diesen Inhalt.
==
vergleicht Inhalt und Referenz;equals()
vergleicht nur Inhaltehttp://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq
a
undb
sind beide string-Referenzen, dann wird das Ergebnis dera == b
hängt nicht davon ab, ob die Referenzen auf das gleiche Objekt zeigen.InformationsquelleAutor user3440463
==
Den = = - operator kann verwendet werden zum vergleichen von zwei Variablen jeglicher Art, und es einfach vergleicht die bits.
Hinweis : es sind mehr Nullen auf der linken Seite der int aber wir kümmern uns nicht um das hier.
int (00000011) == byte b (00000011)
Erinnern, = = - operator kümmert sich nur um das Muster von bits in der variable.
Verwenden,==, Ob zwei Referenzen ("primitive") bezieht sich auf das gleiche Objekt auf dem heap.
Regeln sind die gleichen, ob die variable eine Referenz oder primitiv.
a == c true ist
a == b false ist
die bit-Muster sind die gleichen für a und c, so sind Sie gleich mit ==.
Equal():
Verwenden Sie die equals () - Methode, um zu sehen,, wenn zwei verschiedene Objekte gleich sind.
Wie zwei verschiedene String-Objekte, die beide repräsentieren die Charaktere in "Jane"
object a = 3; object b = 3; Console.WriteLine(a == b);
. Die Ausgabe ist false, obwohl die bit-Muster der Werte sind die gleichen. Die Typen der Operanden auch egal. Der Grund, warum wir den "don' T care", über die unterschiedliche Anzahl der Nullen in deinem Beispiel ist, dass durch die Zeit, die wir rufen Sie die equals-operator, die Anzahl der Nullen ist eigentlich, weil der implizite Konvertierung.InformationsquelleAutor Sanchit
Der einzige Unterschied zwischen Gleich und == ist auf dem Objekttyp-Vergleich. in anderen Fällen, wie bei Referenz-Typen und Wert-Typen, Sie sind fast das gleiche(entweder beide sind bitweise Gleichheit oder Referenz-Gleichheit).
Objekt:
Entspricht: bitweise Gleichheit
==: Referenz-Gleichheit
string: (equals und == den gleichen string, aber wenn ein string geändert-Objekt, dann ist-Vergleich Ergebnis anders sein wird)
Entspricht: bitweise Gleichheit
== : bitweise Gleichheit
Sehen hier weitere Erklärung.
ja, Sie haben Recht, Sie können tun, was Sie wollen, um es zu überschreiben. aber das Thema, das wir sprechen, ist die default-Implementierung. die Standard-Implementierung von Object.Gleich ist bitweise Gleichheit.
InformationsquelleAutor Will Yu