Why must we define both == and != in C#?

后端 未结 13 2169
清酒与你
清酒与你 2020-11-27 08:55

The C# compiler requires that whenever a custom type defines operator ==, it must also define != (see here).

Why?

I\'m curious to k

13条回答
  •  感情败类
    2020-11-27 10:01

    To answer your edit, regarding why you are forced to override both if you override one, it's all in the inheritance.

    If you override ==, most likely to provide some sort of semantic or structural equality (for instance, DateTimes are equal if their InternalTicks properties are equal even through they may be different instances), then you are changing the default behavior of the operator from Object, which is the parent of all .NET objects. The == operator is, in C#, a method, whose base implementation Object.operator(==) performs a referential comparison. Object.operator(!=) is another, different method, which also performs a referential comparison.

    In almost any other case of method overriding, it would be illogical to presume that overriding one method would also result in a behavioral change to an antonymic method. If you created a class with Increment() and Decrement() methods, and overrode Increment() in a child class, would you expect Decrement() to also be overridden with the opposite of your overridden behavior? The compiler can't be made smart enough to generate an inverse function for any implementation of an operator in all possible cases.

    However, operators, though implemented very similarly to methods, conceptually work in pairs; == and !=, < and >, and <= and >=. It would be illogical in this case from the standpoint of a consumer to think that != worked any differently than ==. So, the compiler can't be made to assume that a!=b == !(a==b) in all cases, but it's generally expected that == and != should operate in a similar fashion, so the compiler forces you to implement in pairs, however you actually end up doing that. If, for your class, a!=b == !(a==b), then simply implement the != operator using !(==), but if that rule does not hold in all cases for your object (for instance, if comparison with a particular value, equal or unequal, is not valid), then you have to be smarter than the IDE.

    The REAL question that should be asked is why < and > and <= and >= are pairs for comparative operators that must be implemented concurrently, when in numeric terms !(a < b) == a >= b and !(a > b) == a <= b. You should be required to implement all four if you override one, and you should probably be required to override == (and !=) as well, because (a <= b) == (a == b) if a is semantically equal to b.

提交回复
热议问题