为什么我会收到堆栈溢出异常?

时间:2010-10-12 20:52:18

标签: c# stack-overflow

下面是一个简单的测试程序,在调用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; }
    }
}

4 个答案:

答案 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);

}