2013-06-10 14 views
11

Was sollte in einer CompareTo Methode zurückgegeben werden, wenn das angegebene Objekt null ist?Override CompareTo: Was tun mit Null-Fall?

Die MSDN Library zeigt ein Beispiel, in dem 1 zurückgegeben wird. Aber ich hätte erwartet, einen Fehler zu werfen, weil der Vergleich mit null nicht möglich ist.

Ich erwarte unterschiedliche Meinungen zu dieser Antwort. Was könnte ein Best-Practice-Ansatz sein?

+1

Was meinen Sie, im Vergleich zu null ist "nicht möglich"? Alle Referenztypen können normalerweise mit null verglichen werden. Andernfalls können Sie Dinge mit der [Nullable-Klasse] (http://msdn.microsoft.com/en-us/library/system.nullable.aspx) umbrechen. – Renan

+0

Wenn Sie "unterschiedliche Meinungen erwarten", dann ist dies nicht geeignet für einen Stack-Überlauf, da die FAQ eindeutig besagt, dass Sie es vermeiden sollten, subjektive Fragen zu stellen. –

+1

das Beispiel ist gültig. Da CompareTo die Sortierreihenfolge der Objekte zurückgibt, ist es nicht unerwartet, null als erstes Element zu kategorisieren. – NoviceProgrammer

Antwort

22

Ja, es gibt eine Best Practice. Im Gegensatz zu dem, was die anderen Antworten sagen, gibt es einen erwarteten Standard, nicht nur ein beliebtes Verhalten.

Die richtige Antwort ist in der MSDN-Dokumentation für IComparable<T>.CompareTo und IComparable.CompareTo gegeben:

Per Definition vergleicht jedes Objekt größer als null und zwei null Verweise auf sie gleich zu vergleichen.

(Vertraglich, größer zu vergleichen ist definiert als:. Wenn a > b dann a.CompareTo(b) > 0)

Dieses erwartete Verhalten ist auch in Nullable.Compare<T> beispielsweise bestätigt. Null wird immer als kleiner als ein Wert verglichen.

Es ist auch erwähnenswert, dass für die nicht-generic vergleichen zu können, sollten unpassende Typen nicht als null behandelt werden:

Der Parameter, obj, müssen vom selben Typ wie die Klasse oder Werttyp sein das implementiert diese Schnittstelle; Andernfalls wird eine ArgumentException ausgelöst.


Diese Frage hat keinen Einfluss, aber darüber im Klaren sein, Nullable<T> comparison operators (==, !=, <, <=, >, >=) folgt nicht der IComparable Konvention.

Wenn Sie führen Vergleiche mit Nullable-Typen, wenn der Wert eines der Nullable Types null ist und der andere nicht, alle Vergleiche zu false Ausnahme != (nicht gleich) zu bewerten. Es ist wichtig, nicht zu anzunehmen, dass, weil ein bestimmter Vergleich false zurückgibt, der umgekehrte Fall true zurückgibt. Im folgenden Beispiel ist 10 nicht größer als 0, , kleiner als oder gleich null. Nur num1 != num2 wertet true aus.

Es gibt auch das ungeradee Ergebnis, dass (int?)null == (int?)null true ergibt aber (int?)null <= (int?)null nicht.

2

Sie haben die Wahl. Es ist nicht unmöglich, sich einen gültigen Anwendungsfall vorzustellen, in dem ich etwas mit nichts vergleichen würde und etwas "Größeres" sehen möchte. Aber das ist der Grund, warum Sie es außer Kraft setzen, damit Sie entscheiden können, wie Sie mit diesem Fall umgehen wollen.

1

Die beste Vorgehensweise hängt von Ihrem speziellen Fall ab: Vergleichbar mit null ist möglicherweise abhängig von dem Objekt, das Sie vergleichen.

Wenn ich mein Objekt so definiere, dass null der niedrigste mögliche Wert für einen Vergleich ist, dann ist der Vergleich mit null eindeutig möglich und hat ein wohldefiniertes Ergebnis. In anderen Fällen könnte das Auslösen einer Ausnahme sinnvoller sein.

Letztlich ist dies eine (ziemlich subjektive) Designfrage, auf die es nicht unbedingt eine Antwort gibt.

-1

CompareTo mit Null-Argument beeinflusst den Fall beim Sortieren einer Liste mit Null-Elementen. Durch die Rückgabe von 1, wenn das angegebene Objekt null ist, wird null beim Sortieren nach oben angezeigt, was das beliebteste Verhalten ist.