Comparisons
Comparisons work out-of-box only for primitive types. For others, they need to be defined.
Comparisons do not work well with inheritance. It’s not recommended to implement comparisons on unsealed classes.
IComparable
This interface defines CompareTo
method that returns int
:
- -1 (less than)
- 0 (equal)
- +1 (greater than)
It’s also recommended to implement non-generic IComparable
for legacy code.
This interface is used by arrays to sort their items - if an item does not implement it, exception will be thrown.
Operators
4 operators can be implemented: <
, <=
, >
, >=
. If these get
implemented, it’s recommended to also implement ==
(and !=
).
IComparer
Interface to be implemented by classes that can compare T
. When implementing it,
there’s a convention:
- it two objects are
NULL
return “0” - if the first object is
NULL
, return “-1” - if the second object is
NULL
, return “+1”
There is a recommendation to inherit from Comparer<T>
base class
instead of implementing the interface from zero (because it also implements
non-generic IComparer
, so our inherited class doesn’t have to do that
explicitly).
Comparers are good candidates for singletons.
A good comparer should be deterministic and the result should not depend on the input order. For example, if a class has 2 properties and our comparer sorts them by one of these properties, it might happen that two instances will be considered equal when their second property has different values. So, our comparer should also look at the value of the second property when the first property values are equal.
Writing comparers for non-sealed classes is problematic, mostly due to the problem outlined in the previous paragraph. The result of sorting will depend on the order of input elements since the comparer does not know anything about the inheriting instances (unless it actually does). There is no real solution for this issue.
Comparer<T>.Default
- every type can use the default comparer, which uses the
T’s IComparer<T>
implementation (or IComparer
if the generic one is missing).
What if both are missing? An exception?
StringComparer
is a static class that has 6 various comparers for strings
(implements IComparer
and IEqualityComparer
).