Consider this code:
int a = 0;
short b = 0;
int c = 0;
object a1 = a;
object b1 = b;
object c1 = c;
Console.WriteLine(1);
//comparing primitives - int vs. short
Console.WriteLine(a == b);
Console.WriteLine(b == a);
Console.WriteLine(a.Equals(b));
Console.WriteLine(b.Equals(a));
Console.WriteLine(2);
//comparing objects - int vs. int
Console.WriteLine(c1 == a1);
Console.WriteLine(a1 == c1);
Console.WriteLine(c1.Equals(a1));
Console.WriteLine(a1.Equals(c1));
Console.WriteLine(3);
//comparing objects - int vs. short
Console.WriteLine(a1 == b1);
Console.WriteLine(b1 == a1);
Console.WriteLine(a1.Equals(b1)); //???
Console.WriteLine(b1.Equals(a1));
It prints this output:
1
True
True
True
False
2
False
False
True
True
3
False
False
False
False
What I know; what is clear
Section 2: ==
operator returns true when used with objects only if it compares one object in memory referenced by two different names (not very frequent, but might happen). Equals()
method compare content (value) of the objects. It is mentioned in many answers on this site.
Section 1: Using ==
operator, compiler converts ‘smaller’ type to ‘bigger’ (short
to int
) and compares primitive values. Order of operands (variables) doesn’t matter. Result of Equals()
in the last line might be confusing, because it returns false (doesn’t compare values), but it is understood. The order matter here. As learned in this answer, the best overload must be selected. It is selected by the type of the first variable: short.Equals(short)
. But then int
cannot be converted to ‘smaller’ type (short
), therefore there is no comparison made and method returns false.
Questions:
- Is my understanding above correct?
- Why the last two lines of section 3 (using
Equals()
) both return false? Why is there difference to section 1 line 3? Why isn’t the overload and the value comparison made? It is getting quite abstract and I can’t find the reason.