Soll IEquatable <T>, IComparable <T> für nicht versiegelte Klassen implementiert werden?
Jeder hat eine Meinung darüber, ob oder nichtIEquatable<T>
oderIComparable<T>
sollte in der Regel verlangen, dassT
istsealed
(wenn es eine istclass
)?
Diese Frage stellte sich mir, da ich eine Reihe von Basisklassen schreibe, die bei der Implementierung unveränderlicher Klassen helfen sollen. Ein Teil der Funktionalität, die die Basisklasse bereitstellen soll, ist die automatische Implementierung von Gleichheitsvergleichen (unter Verwendung der Felder der Klasse zusammen mit Attributen, die auf Felder angewendet werden können, um Gleichheitsvergleiche zu steuern). Es sollte ziemlich schön sein, wenn ich fertig bin - ich verwende Ausdrucksbäume, um dynamisch eine kompilierte Vergleichsfunktion für jede zu erstellenT
Daher sollte die Vergleichsfunktion der Leistung einer regulären Gleichheitsvergleichsfunktion sehr nahe kommen. (Ich verwende ein unveränderliches Wörterbuch, auf das ich geschrieben habeSystem.Type
und Double Check Locking, um die generierten Vergleichsfunktionen in einer Weise zu speichern, die angemessen performant ist)
Eine Sache, die jedoch aufgetaucht ist, ist, welche Funktionen verwendet werden müssen, um die Gleichheit der Mitgliedsfelder zu überprüfen. Meine ursprüngliche Absicht war es, zu überprüfen, ob der Typ jedes Mitgliedsfelds (den ich anrufen werde)X
) implementiertIEquatable<X>
. Nach einigem Überlegen glaube ich jedoch nicht, dass dies sicher ist, es sei dennX
istsealed
. Der Grund dafür ist, dass wennX
ist nichtsealed
Ich kann nicht sicher wissen, obX
delegiert die Gleichheitsprüfung in geeigneter Weise an eine virtuelle MethodeX
Dadurch kann ein Subtyp den Gleichheitsvergleich überschreiben.
Dies wirft dann eine allgemeinere Frage auf: Wenn ein Typ nicht versiegelt ist, sollte er diese Schnittstellen überhaupt wirklich implementieren? Ich würde nicht denken, da ich argumentieren würde, dass der Schnittstellenvertrag zwischen zwei zu vergleichen istX
Typen, nicht zwei Typen, die sein können oder nichtX
(obwohl sie natürlich sein müssenX
oder ein Subtyp).
Was denkt ihr? SollteIEquatable<T>
undIComparable<T>
für nicht versiegelte Klassen vermieden werden? (Ich frage mich auch, ob es dafür eine FXCOP-Regel gibt.)
Mein aktueller Gedanke ist, dass meine generierte Vergleichsfunktion nur verwendet wirdIEquatable<T>
auf Mitgliedsfelder derenT
istsealed
, und stattdessen die virtuelle zu verwendenObject.Equals(Object obj)
obT
ist entsiegelt, auch wennT
implementiertIEquatable<T>
, da das Feld möglicherweise Subtypen vonT
und ich bezweifle die meisten umsetzungen vonIEquatable<T>
sind für die Vererbung geeignet.