【问题标题】:'Derived' defines operator == or operator != but does not override Object.Equals(object o) [duplicate]'Derived' 定义 operator == 或 operator != 但不覆盖 Object.Equals(object o) [重复]
【发布时间】:2019-06-05 20:12:26
【问题描述】:

考虑:

  class Base : IEquatable<Base> {
    public bool Equals(Base other) => false;
    public override bool Equals(Object o) => false;
    public override int GetHashCode() => 0;
    public static bool operator ==(Base o1, Base o2) => Equals(o1, o2);
    public static bool operator !=(Base o1, Base o2) => !Equals(o1, o2);
  }

  class Derived : Base {
    public static bool operator ==(Derived o1, Derived o2) => Equals(o1, o2);
    public static bool operator !=(Derived o1, Derived o2) => !Equals(o1, o2);
  }

我明白了:

Warning CS0660  'Derived' defines operator == or operator != but does not override Object.Equals(object o)
Warning CS0661  'Derived' defines operator == or operator != but does not override Object.GetHashCode()

这些警告对我来说是错误的 - 因为我从 Base 继承了被覆盖的 Equals(object)GetHashCode(),所以代码不应该有任何警告。

而且没有什么好办法——

我可以实现Derived中丑陋而多余的功能

我可以添加#pragma warning disable CS0660, CS0661,但这将禁用文件中各处的警告,不仅是在安全派生函数的位置。

这是对 C# 编译器的疏忽还是有充分的理由? 有没有干净的方法?

【问题讨论】:

  • 为什么编译器应该假设Base 上的Equals 以与Derived 上的operator== 相关的任何方式实现逻辑?事实上,在没有另一个的情况下实现一个通常是错误的,因为比较Derived 的逻辑可能比Base 中的Equals 做得更多。
  • 不,我认为这是正确的。如果Base 实现了运算符,那么这将被认为是正确的,但是由于Derived 可能使用Base.Equals 无法获得的信息,编译器不能假设它是Derived.operator == 的适当匹配项,尽管如果你定义了它们就Base.Equals 而言应该,但是太复杂了。只需添加将Derived.Equals 定义为Base.Equals 的覆盖:public override bool Equals(object o) =&gt; base.Equals(o);GetHashCode 相同。
  • 在派生类中重载操作符的唯一原因是你想改变行为。如果您不打算改变行为,那么不要重载运算符,让基类的重载来完成它的工作。
  • @kofifus 他问的问题和你差不多,他也可以像你一样争论为什么他会收到这个警告,因为他继承了Equals(object)GetHashCode() 来自ValueType
  • @kofifus 静态成员继承的,如果你想要技术的话。并不是说在这种情况下它真的很重要。操作符重载是存在的,调用的时候会发现,这才是最重要的。

标签: c#


【解决方案1】:

计算科学通常涉及权衡。

这里的权衡是考虑更可能的错误。

有人忘记添加这些方法的可能性更大吗?还是更有可能有人从另一个类继承并有意保留基类的实现?

我怀疑他们看了这两个并认为“嗯,第一个场景更有可能” - 所以他们针对那个场景进行了优化。

鉴于这是一个警告,就这样吧 - 如果您不同意它,只需禁用(在本地或项目范围内)该警告。这不是错误。

【讨论】:

    猜你喜欢
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2023-03-23
    相关资源
    最近更新 更多