运算符重载和inheritancec#

假设我有一个父类和子类,如下所示

家长class:

class Parent { public string _First; public string _Last; public override bool Equals(object obj) { if (ReferenceEquals(obj, null)) return false; else if (ReferenceEquals(obj, this)) return true; else if (obj is Parent == false) return false; else return this.Equals(obj as Parent) & base.Equals(obj); } public override int GetHashCode() { unchecked { return this._First.GetHashCode() ^ this._Last.GetHashCode() ^ base.GetHashCode(); } } public bool Equals(Parent that) { if (ReferenceEquals(that, null)) return false; else if (ReferenceEquals(that, this)) return true; else return this._First.Equals(that._First) & this._Last.Equals(that._Last); } public static bool operator ==(Parent p1, Parent p2) { return p1.Equals(p2); } public static bool operator !=(Parent p1, Parent p2) { return !p1.Equals(p2); } } 

儿童class:

  class Child : Parent { public string Address; public override bool Equals(object obj) { if (ReferenceEquals(obj, null)) return false; else if (ReferenceEquals(obj, this)) return true; else if (obj is Parent == false) return false; else return this.Equals(obj as Child); } public override int GetHashCode() { unchecked { return this._First.GetHashCode() ^ this._Last.GetHashCode() ^ base.GetHashCode(); } } public bool Equals(Child that) { if (ReferenceEquals(that, null)) return false; else if (ReferenceEquals(that, this)) return true; else return this.Address.Equals(that.Address) & base.Equals(that); } public static bool operator ==(Child p1,Child p2) { return p1.Equals(p2); } public static bool operator !=(Child p1, Child p2) { return !p1.Equals(p2); } } 

以下是比较两个子实例的代码。

  Parent p = new Child() { _First = "Mitul", _Last = "Patel", Address="abc1"}; Parent p1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" }; Child c = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc1" }; Child c1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" }; Console.WriteLine(p.Equals(p1)); Console.WriteLine(p == p1); Console.WriteLine(c.Equals(c1)); Console.WriteLine(c == c1); Console.Read(); 

产量

真假真假

我知道为什么它在第一次比较时给出了真实和真实。 因为它调用父类的重载==()运算符。 我的问题是我想使用子类的==运算符,因为该对象是Child类型,所以它怎么可能呢? 对于静态方法,不能使用虚拟关键字。

谢谢,

在编译时选择运算符的实现。 运算符不是虚方法 – 子类的==运算符不会覆盖父类==运算符。

因此,使编译器选择子==运算符的唯一方法是使变量本身具有类型Child ,例如

  Child p = new Child() { _First = "Mitul", _Last = "Patel", Address="abc1"}; Child p1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" }; 

或者让==运算符调用Equals方法,并使Equals的Child实现覆盖父实现:

在Parent.cs中:

 // No need for these to be public- they should only be called internally. protected virtual bool Equals(Parent that) { if (ReferenceEquals(that, null)) return false; else if (ReferenceEquals(that, this)) return true; else return this._First.Equals(that._First) & this._Last.Equals(that._Last); } 

在Child.cs中:

 // Notice I changed your argument type here... protected override bool Equals(Parent that) { // If we are not dealing with a Child instance, delegate to the base class. if (!(that is typeof(Child))) return base.Equals(that); if (ReferenceEquals(that, null)) return false; else if (ReferenceEquals(that, this)) return true; else return this.Address.Equals(that.Address) & base.Equals(that); } 

static方法在编译时解析,而不是在运行时解析。
对于您的代码, pp1Parent对象,因此它将调用Parent类的==运算符。
如果希望调用派生类的运算符,则必须将它们声明为派生类实例。