The type of your variables is object
, so ==
will be reference equality.
In the string case, both variables refer to the same string "Hello", as .NET interns string literals for performance reasons.
In the integer case, each variable is a different boxed object around the value type integer. Therefore, reference equality is false.
Here is code illustrating what's going on behind the scenes:
string helloString = "hello";
object obj1 = helloString;
object obj2 = helloString;
// Both obj1 and obj2 point to the same object, therefore reference equality returns true.
object obj3 = new object(5); // not a real constructor of System.Object, just for illustration
object obj4 = new object(5);
// obj3 and obj4 refer to different objects (holding the same value), therefore reference equality returns false.
But then why does obj3.Equals(obj4)
returns true? Because Equals
is a virtual method, while operator==
is a static method.
When you call Equals
, even if it's on a variable of type object
, the actual method that will be called is Int32.Equals
, which compares integers by value.
When you call ==
, the operator getting called is from object
, which uses reference equality.