Der C # -Compiler verlangt, dass ein benutzerdefinierter Typ, der den Operator definiert ==
, auch definiert werden muss !=
(siehe hier ).
Warum?
Ich bin gespannt, warum die Designer dies für notwendig hielten und warum der Compiler nicht für einen der Operatoren eine vernünftige Implementierung verwenden kann, wenn nur der andere vorhanden ist. Mit Lua können Sie beispielsweise nur den Gleichheitsoperator definieren und den anderen kostenlos erhalten. C # könnte dasselbe tun, indem Sie aufgefordert werden, entweder == oder beide == und! = Zu definieren und dann den fehlenden Operator! = Automatisch als zu kompilieren !(left == right)
.
Ich verstehe, dass es seltsame Eckfälle gibt, in denen einige Entitäten möglicherweise weder gleich noch ungleich sind (wie IEEE-754 NaNs), aber diese scheinen die Ausnahme und nicht die Regel zu sein. Dies erklärt also nicht, warum die C # -Compiler-Designer die Ausnahme zur Regel gemacht haben.
Ich habe Fälle von schlechter Verarbeitung gesehen, in denen der Gleichheitsoperator definiert ist, dann ist der Ungleichheitsoperator ein Copy-Paste, bei dem jeder Vergleich umgekehrt und jedes && auf ein || umgeschaltet wird (Sie verstehen ... im Grunde! (a == b) erweitert durch De Morgans Regeln). Das ist eine schlechte Praxis, die der Compiler durch Design beseitigen könnte, wie es bei Lua der Fall ist.
Hinweis: Gleiches gilt für Operatoren <> <=> =. Ich kann mir keine Fälle vorstellen, in denen Sie diese auf unnatürliche Weise definieren müssen. Mit Lua können Sie nur <und <= und> = und> natürlich durch die Negation der Formers definieren. Warum macht C # nicht dasselbe (zumindest "standardmäßig")?
BEARBEITEN
Anscheinend gibt es triftige Gründe, dem Programmierer zu erlauben, Überprüfungen auf Gleichheit und Ungleichheit durchzuführen, wie sie möchten. Einige der Antworten weisen auf Fälle hin, in denen dies hilfreich sein kann.
Der Kern meiner Frage ist jedoch, warum dies in C # zwangsweise erforderlich ist, wenn dies normalerweise nicht logisch erforderlich ist.
Es steht auch in auffallendem Kontrast zu Entwurfsentscheidungen für .NET-Schnittstellen wie Object.Equals
, bei IEquatable.Equals
IEqualityComparer.Equals
denen das Fehlen eines NotEquals
Gegenstücks zeigt, dass das Framework !Equals()
Objekte als ungleich betrachtet, und das ist es. Darüber hinaus hängen Klassen wie Dictionary
und Methoden wie .Contains()
ausschließlich von den oben genannten Schnittstellen ab und verwenden die Operatoren nicht direkt, selbst wenn sie definiert sind. Wenn ReSharper Gleichheitsmitglieder generiert, definiert es sowohl ==
als auch !=
in Bezug auf Equals()
und selbst dann nur dann, wenn der Benutzer überhaupt Operatoren generiert. Die Gleichheitsoperatoren werden vom Framework nicht benötigt, um die Objektgleichheit zu verstehen.
Grundsätzlich kümmert sich das .NET Framework nicht um diese Operatoren, sondern nur um einige Equals
Methoden. Die Entscheidung, dass sowohl == als auch! = Operatoren vom Benutzer gemeinsam definiert werden müssen, bezieht sich ausschließlich auf das Sprachdesign und nicht auf die Objektsemantik in Bezug auf .NET.