提问人:rwallace 提问时间:1/17/2017 更新时间:1/17/2017 访问量:716
operator== in base 和 Equals in derived
operator== in base and Equals in derived
问:
我有一个通过引用进行比较的基类,以及一个按值进行比较的派生类(仅显示此处相关的行):
class Term : IReadOnlyList<Term>
public static bool operator ==(Term a, Term b)
{
if (ReferenceEquals(a, null))
return false;
return a.Equals(b);
}
sealed class CompoundTerm : Term, IReadOnlyList<Term>
public override bool Equals(object o)
因此,派生类会重写,但基类必须重载,因为在 和 被声明为 但实际上指向 的上下文中,这是可能的,而且确实很可能会发生。Equals
==
a == b
a
b
Term
CompoundTerm
据我所知 - 如果我错了,请纠正我 - 这都是必要和正确的。
不幸的是,编译器对此并不满意:
Term.cs(40,11): warning CS0660: 'Term' defines operator == or operator != but does not override Object.Equals(object o)
这里最好的事情是什么?我可以使用禁用警告的蛮力解决方案,但我想检查并确保没有更优雅的解决方案,我缺少一些成语。
答:
我有一个通过引用进行比较的基类,以及一个派生类 按值进行比较(仅显示相关的行) 这里)
您当前的实现不一定执行引用相等;它实际上将 的潜在重载称为 。Equals
所以派生类覆盖 Equals,但基类必须重载 == ...
我不明白为什么,如果基类覆盖,则需要在基类中重载。 如果未定义重载,则已执行引用比较,因为静态是在编译时解析的。Equals
==
==
== (object, object)
...在将 a 和 b 声明为 Term 但实际上指向 CompoundTerm 的上下文中,a == b 可能会发生,而且确实很有可能。
呼叫操作员时,真正的类型和是什么无关紧要。 是一个静态方法,因此将根据参数的引用类型进行解析:a
b
==
==
object aString = "Hello";
object theSameString = new string(new[] { 'H', 'e', 'l', 'l', 'o' }); //to avoid string interning
var referenceEquals = aString == theSameString; //false: object == object
var valueEquals = (string)aString == (string)theSameString; //true: string == string
现在,我理解您正在尝试的正是在调用 if 和 are 和 not 子类时执行引用相等,否则执行潜在的值相等。==
a
b
Term
老实说,这似乎相当令人困惑。我建议始终执行引用相等(不要重载它),如果您需要潜在的值相等,请使用并记录类或代码以明确此行为。==
Equals
上一个:看似相同的基元值并不相等
评论
Equals
Equals
Term
Term
AtomicTerm
AtomicTerm.Equals
ReferenceEquals(this, o)
AtomicTerm.GetHashCode
System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(object)
Equals(a, b)