less than 1 minute read

My colleague Ralph and I recently discovered an interesting bit of C# equality behaviour. Consider the following piece of code:

[Test]
public void Equals()
{
    int i = 42;
    short s = 42;

    Assert.IsTrue(i == s);
    Assert.IsTrue(s == i);
    Assert.IsTrue(i.Equals(s));
    Assert.IsTrue(s.Equals(i)); // fails
}

One would expect the last assert to pass, just like the others. The fact that it doesn’t, tells us two things:

  • The behaviour of == and Equals is different on C#’s primitive integral types. At least, when comparing objects of (slightly) different types.
  • Equals is not symmetric when comparing ints with shorts.

Both are surprising to me. While I don’t like pointing out bugs in things like the .NET Framework (it’s like farting: he who points it out, is usually at fault himself), these do seem to qualify; especially the a-symmetry in Equals, which violates the contract.

There’s probably some arcane piece of .NET legacy at work here, so of course, I sent a question to Eric Lippert. I hope I’ll get a response; I’ll post an update if and when I do.

In the mean time: can you, dear readers, offer an explanation?