Ich habe eine komplexe Klasse in meinem C# -Projekt, auf der ich Gleichheitstests durchführen möchte. Es ist keine triviale Klasse; Es enthält eine Vielzahl von Skalareigenschaften sowie Verweise auf andere Objekte und Sammlungen (z. B. IDictionary). Für was es wert ist, ist meine Klasse versiegelt.Überschreiben der Object.Equals() - Instanzmethode in C#; jetzt Code Analyse/FxCop Warnung CA2218: "sollte GetHashCode neu definieren". Soll ich das unterdrücken?
Um eine Leistungsoptimierung an anderer Stelle in meinem System zu ermöglichen (eine Optimierung, die einen kostspieligen Netzwerk-Round-Trip vermeidet), muss ich Instanzen dieser Objekte für Gleichheit – anders als die integrierte Referenz vergleichen können Gleichheit – und so überschreibe ich die Object.Equals() - Instanzmethode. Aber jetzt, dass ich das getan Visual Studio 2008 die Code-Analyse aka FxCop, die ich standardmäßig aktiviert halten, hebt die folgende Warnung:
Warnung: CA2218: Microsoft.Usage: Da 'MySuperDuperClass' definiert Equals neu, es sollte auch GetHashCode neu definieren.
Ich denke, dass ich den Grund für diese Warnung verstehen:Wenn Ich werde solche Objekte als Schlüssel in einer Sammlung zu verwenden, ist der Hash-Code wichtig. d.h. see this question. Allerdings werde ich diese Objekte nicht als Schlüssel in einer Sammlung verwenden. Je.
Gefühl gerechtfertigt, die Warnung zu unterdrücken, ich code CA2218 in the MSDN documentation nachgeschlagen der vollständige Name der Warnung zu erhalten, so konnte ich ein SuppressMessage
Attribut auf meine Klasse gelten wie folgt:
[SuppressMessage("Microsoft.Naming",
"CA2218:OverrideGetHashCodeOnOverridingEquals",
Justification="This class is not to be used as key in a hashtable.")]
Während jedoch weiter zu lesen, ich bemerkte, wie folgt vor:
Wie Fix Verletzungen
Um einen Verstoß gegen diese Regel zu beheben, stellen Sie eine Implementierung von GetHashCode bereit. Für ein Objektpaar des gleichen Typs müssen Sie sicherstellen, dass die Implementierung denselben Wert zurückgibt, wenn Ihre Implementierung von Equals für das Paar den Wert true zurückgibt.
Wenn Warnungen zu unterdrücken
----->Sie eine Warnung dieser Regel nicht unterdrücken. [Pfeil & Hervorhebung von mir]
Also, ich würde gerne wissen: Warum sollte ich nicht unterdrücken diese Warnung als ich vorhatte? Garantiert mein Fall keine Unterdrückung? Ich möchte keine Implementierung von GetHashCode() für dieses Objekt kodieren, das niemals aufgerufen wird, da mein Objekt niemals der Schlüssel in einer Sammlung sein wird. Wenn ich pedantisch sein wollte, statt zu unterdrücken, wäre es vernünftiger für mich, GetHashCode() mit einer Implementierung zu überschreiben, die eine NotImplementedException auslöst?
Update: ich dieses Thema gerade nachgeschlagen wieder in Bill Wagner gutes Buch Effective C#, und er sagt, in "Punkt 10: Verstehen Sie die Fallstricke der GetHashCode()":
Wenn Sie‘ Er definiert einen Typ, der nicht als Schlüssel in einem Container verwendet wird, der nicht von Bedeutung ist. Die Typen , die Fenstersteuerelemente, Web Seitensteuerelemente oder Datenbankverbindungen darstellen, werden wahrscheinlich nicht als Schlüssel in einer Auflistung verwendet. In diesen Fällen tun Sie nichts. Alle Referenztypen haben einen Hash-Code, der korrekt ist, auch , wenn es sehr ineffizient ist. [...] In meisten Arten, die Sie erstellen, ist die beste Ansatz, die Existenz von GetHashCode() vollständig zu vermeiden.
... das ist, wo ich ursprünglich diese Idee hatte, dass ich nicht immer über GetHashCode() besorgt sein muss.
Es vergleicht tatsächlich fast alle Mitglieder der Klasse, um Gleichheit zu bestimmen. Die Klasse enthält Annahmen für eine Reihe von Berechnungen. Jede von ihnen ist anders, um die verschiedenen Objekte zu betrachten. Einige der Annahmen sind Arrays oder Sammlungen anderer Zahlen. Also wäre GetHashCode notwendigerweise so komplex, wenn es (richtig) implementiert wäre. –
@Chris: Es muss nicht sein. Eine einfache, aber oft akzeptable Implementierung besteht darin, die GetHashCode-Werte der Mitglieder zu XOR zu machen. –
Eine noch einfachere und akzeptable (aber normalerweise nicht optimale) Implementierung ist das Zurückgeben des GetHashCode() - Werts von nur einem Feld. Das passiert für eine Struktur. –