ฉันต้องการให้อ็อบเจ็กต์ที่ได้รับคลาส A
บางตัวได้รับการใช้งาน Equals(A other)
ด้วยเช่นกัน ซึ่งจะทำสิ่งต่อไปนี้: หากประเภทของ this
และ other
แตกต่างกัน ให้ส่งคืน false หรือส่งคืน 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>
จะทำให้เกิดข้อผิดพลาดในการรวบรวม) หรือแนวทางของฉันอาจผิดโดยสิ้นเชิง?