I want objects deriving certain class A
to also somehow derive the implementation of the Equals(A other)
that would do the following: if types of this
and other
are different, return false, otherwise return this.value == other.value
.
My attempt looks like this:
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));
}
}
This works fine until we derive more:
public class D : C
{
public D(string value)
: base(value)
{
}
}
then it breaks:
var d = new D("val");
Console.WriteLine(d.Equals(c)); // prints "True"
and now I am stuck. How do I make it work? Both fixing the implementation to work with more than one level of inheritance and preventing more than one level of inheritance are acceptable.
I understand though that I just have to declare all first level descendants of A<T>
as sealed, but that's the last resort unless it can be somehow enforced (so non-sealed descendants of A<T>
would cause compilation error).
Or maybe my approach is wrong completely?