In general, Equals()
methods are not supposed to return true for objects of different types.
a.Equals(b)
calls int.Equals(object)
, which can only return true for boxed Int32
s:
public override bool Equals(Object obj) {
if (!(obj is Int32)) {
return false;
}
return m_value == ((Int32)obj).m_value;
}
b.Equals(a)
calls long.Equals(long)
after implicitly converting the int
to a long
.
It therefore compares the two long
s directly, returning true.
To understand more clearly, look at the IL generated by this simpler example (which prints True False True):
int a = 0;
long b = 0L;
Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));
Console.WriteLine(b.Equals(a));
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldc.i4.0
IL_0003: conv.i8
IL_0004: stloc.1
IL_0005: ldloc.0 //Load a
IL_0006: conv.i8 //Cast to long
IL_0007: ldloc.1 //Load b
IL_0008: ceq //Native long equality check
IL_000A: call System.Console.WriteLine //True
IL_000F: ldloca.s 00 //Load the address of a to call a method on it
IL_0011: ldloc.1 //Load b
IL_0012: box System.Int64 //Box b to an Int64 Reference
IL_0017: call System.Int32.Equals
IL_001C: call System.Console.WriteLine //False
IL_0021: ldloca.s 01 //Load the address of b to call a method on it
IL_0023: ldloc.0 //Load a
IL_0024: conv.i8 //Convert a to Int64
IL_0025: call System.Int64.Equals
IL_002A: call System.Console.WriteLine //True
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…