John Threepwood
John Threepwood

Reputation: 16143

Override CompareTo: What to do with null case?

What should be returned in a CompareTo method when the given object is null?

The MSDN Library shows a example where 1 is returned. But I would have expected to throw an error because comparing to null is not possible.

I expect different opinions to this answer. What could be a best practice approach?

Upvotes: 33

Views: 12918

Answers (4)

jnm2
jnm2

Reputation: 8354

Yes, there is a best practice. Contrary to what the other answers are saying, there is an expected standard, not just a most popular behavior.

The correct answer is given in the MSDN documentation for IComparable<T>.CompareTo and IComparable.CompareTo:

By definition, any object compares greater than null, and two null references compare equal to each other.

(Contractually, comparing greater is defined as: if a > b then a.CompareTo(b) > 0.)

This expected behavior is also borne out for example in Nullable.Compare<T>. Null always compares as less than a value.

It's also worth noting that for the non-generic compare, mismatching types should not be treated as null:

The parameter, obj, must be the same type as the class or value type that implements this interface; otherwise, an ArgumentException is thrown.


This doesn't impact your question, but be aware, Nullable<T> comparison operators (==, !=, <, <=, >, >=) do not follow the IComparable convention.

When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal). It is important not to assume that because a particular comparison returns false, the opposite case returns true. In the following example, 10 is not greater than, less than, nor equal to null. Only num1 != num2 evaluates to true.

There is also the odd result that (int?)null == (int?)null evaluates to true but (int?)null <= (int?)null does not.

Upvotes: 47

tvbusy
tvbusy

Reputation: 156

CompareTo with null argument affects the case when sorting a list with null items. By returning 1 when the given object is null makes null appear on top of the list when sorted, which is the most popular behavior.

Upvotes: 1

Dan Puzey
Dan Puzey

Reputation: 34200

The best practise would depend on your particular case: comparing to null might be possible depending on the object you're comparing.

If I define my object such that null is the lowest possible value for any comparison, then comparing to null is clearly possible and has a well-defined result. In other cases, throwing an exception might make more sense.

Ultimately, this is a (fairly subjective) design question, to which there's not necessarily one answer.

Upvotes: 1

Bill Gregg
Bill Gregg

Reputation: 7147

The choice is yours. It's not beyond the realm of possibility to imagine a valid use case where I'd compare something to nothing, and want "something" to be seen as greater. But that's why you are overriding it, so you can decide how you want to handle that case.

Upvotes: 2

Related Questions