Below is a simple test program that throws a StackOverflowException
when Equals
is called. I expected the generic Equals
that I got from object to call my IEquatable<MyClass>.Equals
, but it does not, it calls itself instead. Why? The parameter type seems ok. Why does it call the generic version in the first place? I am confused.
using System;
namespace consapp
{
class Program
{
static void Main(string[] args)
{
MyClass x0 = new MyClass("x0");
MyClass x1 = new MyClass("x");
Console.WriteLine(x1.Equals(x0));
}
}
internal class MyClass : IEquatable<MyClass>
{
public string Name { get; set; }
public MyClass(string s) { this.Name = s; }
public override bool Equals(object x) { return this.Equals(x as MyC开发者_StackOverflow中文版lass); }
public override int GetHashCode() { return this.Name.ToLowerInvariant().GetHashCode(); }
bool IEquatable<MyClass>.Equals(MyClass x) { return x != null && this.Name == x.Name; }
}
}
IEquatable.Equals
is implemented explicitly. You have to cast the class to the interface first to use an explicit implementation:
public override bool Equals(object x)
{
return (this as IEquatable).Equals(x as MyClass);
}
Otherwise it will keep on calling itself in an infinite recursion, yielding in a StackoverflowException eventually.
public override bool Equals(object x) { return this.Equals(x as MyClass); }
The above line is causing it.
You will have to change it to
public override bool Equals(object x)
{
return ((IEquatable<MyClass>)this).Equals(x as MyClass);
}
If you want to call Object's Equals in your Equal override, you should call base.Equals, not this.Equals.
And note that Object's Equals just compares the references, not the contents.
Try
public override bool Equals(object x) {
Console.Write("equals! ");
return this.Equals(x as MyClass);
}
精彩评论