【问题标题】:operator overloading and inheritance c#运算符重载和继承 c#
【发布时间】:2012-05-09 20:27:27
【问题描述】:

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

父类:

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);
    }

}

这是比较两个 child 实例的代码。

 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 关键字。

谢谢,

【问题讨论】:

    标签: c# inheritance operator-overloading


    【解决方案1】:

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

    因此,让编译器选择子 == 运算符的唯一方法是让变量本身的类型为 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);
    }
    

    【讨论】:

    • 感谢克里斯。是的,让 Equals 方法在父级中成为虚拟是有意义的。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多