2012-05-09 102 views
3

比方說,我有一個父類和子類,如下操作符重載和繼承C#

父類:

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 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類型,所以它怎麼可能?對於靜態方法,virtual關鍵字不能使用。

謝謝,

回答

8

在編譯時選擇運算符的實現。運算符不是虛方法 - 子類的==運算符不會覆蓋父類==運算符。因此,編譯器選擇子操作符==的唯一方法是讓變量本身的類型爲Child,例如,

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

或有==操作員呼叫Equals方法,使的Equals的兒童實現覆蓋父類的實現:

在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); 
} 
+0

謝謝克里斯。是的,這有意義使Equals方法在父項中是虛擬的。 – mchicago

1

static方法在co mpile時間,而不是在運行時間。
對於您的代碼pp1Parent對象,所以它會調用Parent類的==運算符。
如果您希望調用派生類的運算符,則必須將它們聲明爲派生類實例。