Ich weiß, dass ich Boxen vermeiden kann, indem ich meine eigene Equals-Implementierung hinzufüge.
%Vor% Ich kann das nicht so sehr als Overload bezeichnen. Durch die Magie der Laufzeit ruft es korrekt die richtige Equals()
Implementierung basierend auf dem Typ des Aufrufers auf.
Warum kann ich den Parametertyp nicht auf TwoDoubles
überschreiben und ändern und das Boxen bei Bedarf auf der Grundlage der Laufzeit zulassen? Liegt das daran, dass C # die Parameterkontravierung nicht unterstützt (wenn das der Grund ist, warum wird es nicht unterstützt ... scheint ein kleiner Schritt von object o = new TwoDoubles()
zu sein)?
UPDATE
Klarstellung: object
ist ein Teil der Vererbungshierarchie einer Struktur. Warum können wir keinen abgeleiteten Typ als Parameter angeben, um eine Implementierung von einem weniger abgeleiteten Typ zu überschreiben? Dies würde uns erlauben zu schreiben:
Dies sollte aufgerufen werden, wenn die Variable ein TwoDouble ist, selbst wenn die Variable in einen Objekttyp eingereiht wurde.
Warum kann ich den Parametertyp nicht auf TwoDoubles überschreiben und ändern?
Weil das nicht typsicher wäre!
%Vor%Und jetzt hast du einen Tiger an eine Methode übergeben, die eigentlich nur eine Giraffe braucht!
Das Gleiche gilt für Ihren Fall. Sie überschreiben eine Methode, die jedes Objekt mit einer Methode akzeptiert, die nur eine Struktur annehmen kann; das ist nicht typsicher.
Liegt das daran, dass C # den Parametertyp contravariance nicht unterstützt?
Nein, weil Sie nach dem Parametertyp Kovarianz fragen, der nicht typsicher ist.
C # unterstützt ebenfalls keine Kontravarianz des Parametertyps, aber das ist nicht das, wonach Sie fragen.
Sie können den Parameter (Überladung) für Equals
genau so ändern, wie Sie es getan haben, und das Boxen wird nach Bedarf ausgeführt (d. h. wann immer Equals (object) aufgerufen wird)
Da alles vom Objekt erbt (oder implizit durch Boxen), können Sie nicht verhindern, dass Personen Equals (Objekt) für Ihren Typ verwenden können. Auf diese Weise erhalten Sie jedoch einen umgangenen Anruf.
Wenn Sie den aufrufenden Code kontrollieren, verwenden Sie immer Ihre neue überladene Option, d. h. Equals(TwoDouble)
Beachten Sie, dass Ihr Code, wie schon ein Kommentator sagte, etwas falsch ist, tun Sie dies stattdessen:
%Vor% BEARBEITEN wie es klug vorgeschlagen wurde, sollten Sie die gleiche Aufgabe ausführen, aber mithilfe der IEquatable-Schnittstelle, in diesem Fall IEquatable<TwoDouble>
(beachten Sie, keine Codeänderung von dem, was wir getan haben, als erforderlich es entspricht der Signatur)
Wenn es so funktioniert, wie Sie es vorgeschlagen haben, wo public override bool Equals(TwoDoubles c) { return m_Re == c.m_Re && m_Im == c.m_Im; }
alles war, was nötig war, um die Methode Equals(object)
zu überschreiben, was würde dieser Code tun?
Was soll in Zeile 3 passieren?
Equals(TwoDouble)
aufrufen? Wenn ja, mit welchem Parameter? Ein Standard TwoDouble mit allen Nullen? Das würde gegen die Regeln der Gleichheit verstoßen. Es gibt keine gute Möglichkeit, dies zu implementieren, und es verursacht schnell mehr Probleme, als es löst.
Tags und Links c#