akonsu
akonsu

Reputation: 29586

Why do I get a stack overflow exception?

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 MyClass); }
        public override int GetHashCode() { return this.Name.ToLowerInvariant().GetHashCode(); }
        bool IEquatable<MyClass>.Equals(MyClass x) { return x != null && this.Name == x.Name; }
    }
}

Upvotes: 1

Views: 753

Answers (4)

shahkalpesh
shahkalpesh

Reputation: 33484

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); 
}

Upvotes: 1

Novikov
Novikov

Reputation: 4489

Try

public override bool Equals(object x) {
    Console.Write("equals! ");
    return this.Equals(x as MyClass);

}

Upvotes: 0

Timores
Timores

Reputation: 14599

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.

Upvotes: 0

Femaref
Femaref

Reputation: 61497

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.

Upvotes: 10

Related Questions