Warum gibt es keine NullableT.Equals (T-Wert) -Methode? [geschlossen]

8

Beginnen wir mit einem sehr einfachen Code:

%Vor%

Das Ergebnis ist 4xtrue. Ändern wir nun den Typ einer Variablen d in dezimal? :

%Vor%

Diesmal wird das Ergebnis Wahr, Wahr, Falsch, Wahr sein. Die Erklärung dieser Situation ist ziemlich einfach. Die Equals -Methode wird wie folgt für Nullable & lt; T & gt; -Typ implementiert:

%Vor%

Wenn this einen Wert hat und anderer -Parameter nicht null ist, wird Decimal.Equals (Objektwert) aufgerufen. Decimal.Equals (Objektwert) -Methode funktioniert auf diese Weise, wenn der Wert -Parameter nicht dezimal ist, dann wird das Ergebnis immer sein falsch .

Mir scheint, dass die aktuelle Implementierung nicht intuitiv ist und ich frage mich, warum Nullable Entwicklern keine generische Version von Equals zur Verfügung stellt, zB:

%Vor%

War es absichtlich oder ist es eine Unterlassung?

Kommentar 1:

Ein kurzer Kommentar um klar zu sein. Ich schlug vor, dass Nullable & lt; T & gt; zwei Equals -Methoden haben sollte, dh: public override bool Equals (anderes Objekt) und public bool Equals (T andere)

    
Michał Komorowski 11.09.2013, 07:44
quelle

2 Antworten

3

Anstatt (decimal)2 zu schreiben, kannst du 2m schreiben (wird das im folgenden verwenden).

Wenn Sie den Operator == verwenden, tritt kein Boxing auf. Der C # -Compiler wählt die vordefinierte Überladung (d. H. Die in der C # -Sprachspezifikation definierte Überladung; dies ist nicht notwendigerweise eine echte .NET-Methode) von operator == , die am besten übereinstimmt.

Es gibt Überladungen:

%Vor%

Es gibt keine "gemischten" Überladungen wie operator ==(decimal x, int y); . Da eine implizite Konvertierung von int nach decimal existiert, wird Ihr Literal 2 implizit in 2m konvertiert, wenn Sie == verwenden.

Mit Equals tritt in manchen Situationen boxen auf. Dafür brauchst du keine Nullables. Um all diese Aufrufe zu nennen:

%Vor%

gib false zurück! "Zwei" vom Typ Int32 ist nicht gleich "zwei" vom Typ Decimal .

Nur wenn das Überladen der Methode zu einer Konvertierung zwischen int und decimal führt, ist das Ergebnis true . Zum Beispiel:

%Vor%

Obwohl eine zusätzliche Überladung von Equals zu Nullable<> hinzugefügt werden konnte, ist das von Ihnen beschriebene Verhalten nicht wirklich auf Nullable<> bezogen.

    
Jeppe Stig Nielsen 11.09.2013, 10:31
quelle
1

Obwohl mir diese Fragen gefallen, können sie nur von denen des verantwortlichen Designteams beantwortet werden. Eine offensichtliche Problemumgehung besteht darin, auf das Value zuzugreifen, das T ist, und das Equals davon zu verwenden.

Meine beste Schätzung ist, dass es wahrscheinlich alle T zu IEquatable<T> zwingen würde, um generisch auf Equals<T> auf einen bestimmten Typ zuzugreifen. Dies würde für die Kernwerktypen funktionieren, aber andere .NET-Strukturen würden diese Schnittstelle nicht unbedingt implementieren und enum -Typen nicht.

Ich nehme an, es könnte mit type checking / casting gemacht werden, aber das kostet dann viel Arbeit im Vergleich zum Aufrufer einfach: myNullable.GetValueOrDefault().Equals() .

Sie können eine Erweiterungsmethode für diese Aufgabe erstellen, damit sie die Methode aufruft, die Sie benötigen, um das generische Argument explizit anzugeben (andernfalls ruft der Compiler Equals(object) :

auf %Vor%

Ich habe eine Frage gestellt, warum dieser Anruf wird benötigt.

Der Grund, warum es in die Erweiterungsmethode gezwungen werden muss, liegt an der Compilerimplementierung, die nur Erweiterungsmethoden verwendet, wenn keine geeignete Methode existiert. In diesem Fall wird Equals(object) als geeigneter als Equals<T>(T) als letzter angesehen ist eine Erweiterungsmethode. Es ist in der Spezifikation.

    
Adam Houldsworth 11.09.2013 07:55
quelle

Tags und Links