A
Alex Cohn
In C++, there is an easy technique to provide an overloaded Equals() method.
A straightforward translation to C# causes a stack overflow. Why does
b.Equals(ba) in the snippet below not understand that it should call (ba as
B).Equals(b) inside?
Thanks in advance,
Alex
code sample follows:
class A
{
protected int a = 1;
public A() {}
public override bool Equals(object obj)
{
return obj.Equals(this);
}
public virtual bool Equals(A obj)
{
return obj.a == this.a;
}
}
class B : A
{
private static int cnt = 0;
protected int b = 2;
public B() { a = cnt++; }
public override bool Equals(A obj)
{
return obj.Equals(this);
}
public virtual bool Equals(B obj)
{
return obj.b == this.b;
}
}
static void Main(string[] args)
{
A a = new A();
A a1 = new A();
B b = new B();
B b1 = new B();
A ba = new B();
Console.WriteLine(a.Equals(a1)); // OK, prints true
Console.WriteLine(a.Equals(b)); // OK, prints false
Console.WriteLine(b.Equals(a)); // OK, prints false
Console.WriteLine(b.Equals(b1)); // OK, prints true
Console.WriteLine(b.Equals(ba)); // stack overflow
Console.WriteLine(ba.Equals(b)); // stack overflow
}
PS I know a workaround for this problem, but it looks ugly to me:
B.Equals should be written as:
public override bool Equals(A obj)
{
B Bobj = obj as B;
if (Bobj != null)
return Bobj.Equals(this);
else
return obj.Equals(this);
}
This solution does not satisfy me becasue it is equivalent to writing the
case of obj being of class B explicitly, like this:
public override bool Equals(A obj)
{
B Bobj = obj as B;
if (Bobj != null)
return this.b == Bobj.b;
else
return obj.Equals(this);
}
A straightforward translation to C# causes a stack overflow. Why does
b.Equals(ba) in the snippet below not understand that it should call (ba as
B).Equals(b) inside?
Thanks in advance,
Alex
code sample follows:
class A
{
protected int a = 1;
public A() {}
public override bool Equals(object obj)
{
return obj.Equals(this);
}
public virtual bool Equals(A obj)
{
return obj.a == this.a;
}
}
class B : A
{
private static int cnt = 0;
protected int b = 2;
public B() { a = cnt++; }
public override bool Equals(A obj)
{
return obj.Equals(this);
}
public virtual bool Equals(B obj)
{
return obj.b == this.b;
}
}
static void Main(string[] args)
{
A a = new A();
A a1 = new A();
B b = new B();
B b1 = new B();
A ba = new B();
Console.WriteLine(a.Equals(a1)); // OK, prints true
Console.WriteLine(a.Equals(b)); // OK, prints false
Console.WriteLine(b.Equals(a)); // OK, prints false
Console.WriteLine(b.Equals(b1)); // OK, prints true
Console.WriteLine(b.Equals(ba)); // stack overflow
Console.WriteLine(ba.Equals(b)); // stack overflow
}
PS I know a workaround for this problem, but it looks ugly to me:
B.Equals should be written as:
public override bool Equals(A obj)
{
B Bobj = obj as B;
if (Bobj != null)
return Bobj.Equals(this);
else
return obj.Equals(this);
}
This solution does not satisfy me becasue it is equivalent to writing the
case of obj being of class B explicitly, like this:
public override bool Equals(A obj)
{
B Bobj = obj as B;
if (Bobj != null)
return this.b == Bobj.b;
else
return obj.Equals(this);
}