Why do I have to overload operators when implementing CompareTo?

前端 未结 2 1819
名媛妹妹
名媛妹妹 2021-02-02 07:08

Let\'s say I have a type that implements IComparable.

I would have thought it\'s reasonable to expect that the operators ==, !=, >

2条回答
  •  青春惊慌失措
    2021-02-02 07:58

    Two main reasons:

    1. It is a general structure for all operators. While the comparison operators may never have alternative semantics, there is great utility in a structure that allows very different semantics for some of the other operators. Implementing a separate structure for just the comparison operators would have required omitting some other, probably much more useful, feature. Check out this elegant implementation of BNF within C# for an example.
    2. The default implementations, for the case of value types that have it, relies of necessity on Reflection, and thus is horribly inefficient. Only you actually know the most efficient way to implement these operators for your classes. In many cases not all fields of a struct need to be compared to test equality, nor do all fields always need to be combined in a suitable GetHashCode implementation. No default implementation can ever determine that for all types, because it is reducible to the Halting Problem.

    Update as per Eric Lippert among others, the following is the appropriate standard implementation of the comparison operators in C# for a type UDT:

    public int  CompareTo(UDT x) { return CompareTo(this, x); }
    public bool Equals(UDT x)    { return CompareTo(this, x) == 0; }
    public static bool operator  < (UDT x, UDT y) { return CompareTo(x, y)  < 0; }
    public static bool operator  > (UDT x, UDT y) { return CompareTo(x, y)  > 0; }
    public static bool operator <= (UDT x, UDT y) { return CompareTo(x, y) <= 0; }
    public static bool operator >= (UDT x, UDT y) { return CompareTo(x, y) >= 0; }
    public static bool operator == (UDT x, UDT y) { return CompareTo(x, y) == 0; }
    public static bool operator != (UDT x, UDT y) { return CompareTo(x, y) != 0; }
    public override bool Equals(object obj)
    {
        return (obj is UDT) && (CompareTo(this, (UDT)obj) == 0);
    }
    

    Just add the custom definition for private static int CompareTo(UDT x, UDT y) and stir.

提交回复
热议问题