在子类和抽象类上等于运算符

时间:2019-03-12 04:49:09

标签: c# inheritance operator-overloading

假设我们有以下简单的类:

abstract class Abc { }

class Bcd : Abc { public int val; }

默认情况下,在此示例中,==实例上的Bcd运算符将返回false:

var result_1 = new Bcd() { val = 10 } == new Bcd() { val = 10 };

因此,按照指南here,可以将==运算符添加到Bcd

class Bcd : Abc
{
    public int val;

    public bool Equals(Bcd obj)
    {
        if (Object.ReferenceEquals(obj, null)) return false;
        if (Object.ReferenceEquals(obj, this)) return true;
        if (obj.GetType() != GetType()) return false;

        return obj.val == val;
    }

    public override bool Equals(object obj) => Equals(obj as Bcd);

    public override int GetHashCode() => val.GetHashCode();

    public static bool operator ==(Bcd a, Bcd b)
    {
        if (Object.ReferenceEquals(a, null))
        {
            if (Object.ReferenceEquals(b, null)) return true;

            return false;
        }

        return a.Equals(b);
    }

    public static bool operator !=(Bcd a, Bcd b) => !(a == b);
}

现在,表达式的计算结果为true:

var result_1 = new Bcd() { val = 10 } == new Bcd() { val = 10 };

但是,我可能想将Bcd的实例(以及Abc的其他子类的其他实例)存储在类型为Abc的变量中:

Abc a = new Bcd() { val = 10 };
Abc b = new Bcd() { val = 10 };

现在,这当然会返回false:

var result_2 = a == b;

获得所需行为的一种方法是也向Abc添加相等方法(即使它是抽象类):

abstract class Abc
{
    public bool Equals(Abc obj)
    {
        if (obj is Bcd && this is Bcd) return (obj as Bcd) == (this as Bcd);

        return false;
    }

    public static bool operator ==(Abc a, Abc b)
    {
        if (Object.ReferenceEquals(a, null))
        {
            if (Object.ReferenceEquals(b, null)) return true;

            return false;
        }

        return a.Equals(b);
    }

    public static bool operator !=(Abc a, Abc b) => !(a == b);
}

现在表达式返回true

Abc a = new Bcd() { val = 10 };
Abc b = new Bcd() { val = 10 };

var result_2 = a == b;

我的问题是,是否以上述推荐方法将相等运算符(和Equals方法,!=运算符等)添加到抽象父类Abc中?感觉有点样板。此外,如果将来再次Abc进行子类化,则Equals中的Abc运算符需要更新;这也感觉有点奇怪。

此模式是否有推荐的指南?

0 个答案:

没有答案