派生 类 的通用相等性实现
Generic equality implementation for derived classes
我希望派生某些 class A
的对象也以某种方式派生 Equals(A other)
的实现,它将执行以下操作:如果类型为 this
和 other
不同,return false,否则return this.value == other.value
.
我的尝试是这样的:
public class A<T> : IEquatable<A<T>>
where T: A<T>
{
protected string Value { get; }
public A(string value)
{
Value = value;
}
public bool Equals(A<T> other)
{
var concrete = other as T;
if (concrete == null)
{
return false;
}
return concrete.Value == Value;
}
}
public class B : A<B>
{
public B(string value)
: base(value)
{
}
}
public class C : A<C>
{
public C(string value)
: base(value)
{
}
}
class Program
{
static void Main(string[] args)
{
var b1 = new B("val");
var b2 = new B("val");
var c = new C("val");
Console.WriteLine(b1.Equals(b1));
Console.WriteLine(b1.Equals(b2));
Console.WriteLine(b2.Equals(b1));
Console.WriteLine(b1.Equals(c));
Console.WriteLine(b2.Equals(c));
Console.WriteLine(c.Equals(b1));
Console.WriteLine(c.Equals(b2));
}
}
在我们推导出更多之前,这工作正常:
public class D : C
{
public D(string value)
: base(value)
{
}
}
然后它坏了:
var d = new D("val");
Console.WriteLine(d.Equals(c)); // prints "True"
现在我卡住了。我如何让它发挥作用?
修复实现以处理多级继承和防止多级继承都是可以接受的。
我知道我只需要将 A<T>
的所有一级后代声明为密封的,但这是最后的手段,除非它可以以某种方式强制执行(因此 A<T>
的非密封后代会导致编译错误)。
或者我的方法完全错误?
这都是因为 as
运算符可以毫无问题地将子类转换为超类。
你要做的是检查类型,看看它们是否相等:
if (this.GetType() == other.GetType()) {
return false;
}
这个question有点相关,关于GetType
、typeof
和is
的行为,类似于as
。
我希望派生某些 class A
的对象也以某种方式派生 Equals(A other)
的实现,它将执行以下操作:如果类型为 this
和 other
不同,return false,否则return this.value == other.value
.
我的尝试是这样的:
public class A<T> : IEquatable<A<T>>
where T: A<T>
{
protected string Value { get; }
public A(string value)
{
Value = value;
}
public bool Equals(A<T> other)
{
var concrete = other as T;
if (concrete == null)
{
return false;
}
return concrete.Value == Value;
}
}
public class B : A<B>
{
public B(string value)
: base(value)
{
}
}
public class C : A<C>
{
public C(string value)
: base(value)
{
}
}
class Program
{
static void Main(string[] args)
{
var b1 = new B("val");
var b2 = new B("val");
var c = new C("val");
Console.WriteLine(b1.Equals(b1));
Console.WriteLine(b1.Equals(b2));
Console.WriteLine(b2.Equals(b1));
Console.WriteLine(b1.Equals(c));
Console.WriteLine(b2.Equals(c));
Console.WriteLine(c.Equals(b1));
Console.WriteLine(c.Equals(b2));
}
}
在我们推导出更多之前,这工作正常:
public class D : C
{
public D(string value)
: base(value)
{
}
}
然后它坏了:
var d = new D("val");
Console.WriteLine(d.Equals(c)); // prints "True"
现在我卡住了。我如何让它发挥作用? 修复实现以处理多级继承和防止多级继承都是可以接受的。
我知道我只需要将 A<T>
的所有一级后代声明为密封的,但这是最后的手段,除非它可以以某种方式强制执行(因此 A<T>
的非密封后代会导致编译错误)。
或者我的方法完全错误?
这都是因为 as
运算符可以毫无问题地将子类转换为超类。
你要做的是检查类型,看看它们是否相等:
if (this.GetType() == other.GetType()) {
return false;
}
这个question有点相关,关于GetType
、typeof
和is
的行为,类似于as
。