I'm trying to implement the IEquatable<T> interface and == operator. The implementation below triggers a NullReferenceException when I try to use the == operator despite the fact that both operands are non-null. I've added comments to the minimum example code to show exactly where the exception occurs. What am I doing wrong?
using System;
namespace scratchpad
{
class TestClass : IEquatable<TestClass>
{
public int data;
public TestClass(int d)
{
this.data = d;
}
public bool Equals(TestClass other)
{
if (other == null)
return false;
else
return this.data == other.data;
}
public override bool Equals(object other)
{
if (other is TestClass)
return this.Equals((TestClass)other);
else //Includes null
return false;
}
public override int GetHashCode()
{
return this.data;
}
public static bool operator ==(TestClass left, TestClass right)
{
return left.Equals(right); //This line triggers the NullReferenceException
}
public static bool operator !=(TestClass left, TestClass right)
{
return !left.Equals(right);
}
}
class Program
{
static void Main(string[] args)
{
TestClass tc1 = new TestClass(10);
TestClass tc2 = new TestClass(10);
Console.WriteLine("tc1="+tc1.data); //Prints "tc1.data=10" fine
Console.WriteLine("tc1="+tc1.data); //Prints "tc2.data=10" fine
bool isEqual = tc1 == tc2; //NullReferenceException occur here
Console.WriteLine("isEqual="+isEqual); //Never gets to here
}
}
}
Edit (to clarify question in response to duplicates question flags):
I am not asking what a NullReferenceException is (I understand that) and I am not interested in ReferenceEquals as I need to equate the object's values.
Actually, your overloaded equality operator is hit three times:
First, when called from
Program.Main(string[])with the linetc1 == tc2, whereleft=tc1andright=tc2, which then callsTestClass.Equals(TestClass)whereother=tc2.From there,
other == nullnow calls your overloaded equality operator a second time, whereleft=tc2andright=null. Now,TestClass.Equals(TestClass)is called also a second time, whereother=null.And finally,
other == nullcalls your overloaded equality operator for a third time, where bothleft=nullandright=null. This now eventually causes the System.NullReferenceException because left was null.To fix this coding error, replace
other == nullwithother is nullinTestClass.Equals(TestClass):Alternatively, as conditional expression (using expression body):