假设我们有以下简单的类:
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
运算符需要更新;这也感觉有点奇怪。
此模式是否有推荐的指南?