c#编译器要求每当自定义类型定义operator ==时,它也必须定义!=(参见这里)。
Why?
我很好奇为什么设计人员认为这是必要的,为什么编译器不能默认为一个合理的实现操作符时,只有另一个存在。例如,Lua只允许定义相等操作符,而免费获得另一个。c#也可以做到这一点,要求你定义==或同时定义==和!=,然后自动将缺少的!=运算符编译为!(左==右)。
我知道有一些奇怪的极端情况,一些实体可能既不相等也不相等(如IEEE-754 NaN),但这些似乎是例外,而不是规则。因此,这并不能解释为什么c#编译器设计人员将例外设置为规则。
我见过一些糟糕的情况,其中定义了相等运算符,然后不等式运算符是一个复制粘贴,每个比较都反转,每个&&切换到||(你明白了吧……(a==b)通过德摩根法则展开)。这是编译器可以通过设计消除的不良实践,就像Lua一样。
注意: 运算符< > <= >=也是如此。我无法想象在哪些情况下需要用非自然的方式来定义它们。Lua只允许您定义<和<=,并通过前两者的否定自然地定义>=和>。为什么c#不做同样的事情(至少在默认情况下)?
EDIT
显然,有充分的理由允许程序员根据自己的喜好执行相等和不相等的检查。一些答案指向了这样做可能不错的案例。
然而,我问题的核心是,为什么在c#中这是强制要求的,而通常这在逻辑上是不必要的?
It is also in striking contrast to design choices for .NET interfaces like Object.Equals, IEquatable.Equals IEqualityComparer.Equals where the lack of a NotEquals counterpart shows that the framework considers !Equals() objects as unequal and that's that. Furthermore, classes like Dictionary and methods like .Contains() depend exclusively on the aforementioned interfaces and do not use the operators directly even if they are defined. In fact, when ReSharper generates equality members, it defines both == and != in terms of Equals() and even then only if the user chooses to generate operators at all. The equality operators aren't needed by the framework to understand object equality.
基本上,. net框架并不关心这些操作符,它只关心一些Equals方法。要求用户同时定义==和!=操作符的决定纯粹与语言设计有关,而与. net关心的对象语义无关。