下面是一个简单的测试程序,在调用StackOverflowException
时抛出Equals
。我期望从对象获取的泛型Equals
可以调用我的IEquatable<MyClass>.Equals
,但它没有,它会调用自己。为什么?参数类型似乎没问题。为什么它首先称为通用版本?我很困惑。
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 MyClass); }
public override int GetHashCode() { return this.Name.ToLowerInvariant().GetHashCode(); }
bool IEquatable<MyClass>.Equals(MyClass x) { return x != null && this.Name == x.Name; }
}
}
答案 0 :(得分:9)
IEquatable.Equals
已明确实施。您必须首先将类强制转换为接口以使用显式实现:
public override bool Equals(object x)
{
return (this as IEquatable).Equals(x as MyClass);
}
否则它将继续在无限递归中调用自身,最终在StackoverflowException中产生。
答案 1 :(得分:1)
public override bool Equals(object x) { return this.Equals(x as MyClass); }
以上一行是造成它的。
您必须将其更改为
public override bool Equals(object x)
{
return ((IEquatable<MyClass>)this).Equals(x as MyClass);
}
答案 2 :(得分:0)
如果你想在Equal覆盖中调用Object的Equals,你应该调用base.Equals,而不是this.Equals。
请注意,Object的Equals只是比较引用,而不是内容。
答案 3 :(得分:0)
尝试
public override bool Equals(object x) {
Console.Write("equals! ");
return this.Equals(x as MyClass);
}