Saya ingin objek yang menurunkan kelas tertentu A
juga memperoleh implementasi Equals(A other)
yang akan melakukan hal berikut: jika tipe this
dan other
berbeda, kembalikan false, jika tidak, kembalikan this.value == other.value
.
Upaya saya terlihat seperti ini:
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));
}
}
Ini berfungsi dengan baik sampai kita mendapatkan lebih banyak:
public class D : C
{
public D(string value)
: base(value)
{
}
}
lalu rusak:
var d = new D("val");
Console.WriteLine(d.Equals(c)); // prints "True"
dan sekarang aku terjebak. Bagaimana cara membuatnya berhasil? Memperbaiki implementasi agar berfungsi dengan lebih dari satu tingkat warisan dan mencegah lebih dari satu tingkat warisan dapat diterima.
Namun saya mengerti bahwa saya hanya perlu mendeklarasikan semua keturunan tingkat pertama A<T>
sebagai tersegel, tapi itu adalah pilihan terakhir kecuali jika itu dapat ditegakkan (sehingga keturunan A<T>
yang tidak tersegel akan menyebabkan kesalahan kompilasi). Atau mungkin pendekatan saya salah total?