A strange piece of code I’ve just discovered in C# (should also be true for other CLI languages using .NET’s structs).
using System;
public class Program
{
public static void Main(string[] args)
{
int a;
long b;
a = 0;
b = 0;
Console.WriteLine(a.Equals(b)); // False
Console.WriteLine(a.Equals(0L)); // False
Console.WriteLine(a.Equals((long)0)); // False
Console.WriteLine(a.Equals(0)); // True
Console.WriteLine(a.Equals(a)); // True
Console.WriteLine(a == b); // True
Console.WriteLine(a == 0L); // True
Console.WriteLine();
Console.WriteLine(b.Equals(a)); // True
Console.WriteLine(b.Equals(0)); // True
Console.WriteLine(b.Equals((int)0)); // True
Console.WriteLine(b.Equals(b)); // True
Console.WriteLine(b == a); // True
Console.WriteLine(b == 0); // True
}
}
Two interesting points here (assuming that a is int and b is long):
a != b, butb == a;(a.Equals(b)) != (a == b)
Is there any reason why comparison was implemented this way?
Note: .NET 4 was used if it makes any difference.
In general,
Equals()methods are not supposed to return true for objects of different types.a.Equals(b)callsint.Equals(object), which can only return true for boxedInt32s:b.Equals(a)callslong.Equals(long)after implicitly converting theintto along.It therefore compares the two
longs directly, returning true.To understand more clearly, look at the IL generated by this simpler example (which prints True False True):