You are boxing the int
by assigning it to an Object
variable. That creates a new instance and ==
in System.Object
compares references, they are different, so it returns false
.
If you would cast it back(unbox) to an int
the ==
would work as expected:
object oneO = one;
object oneOneO = oneOne;
int newOne = (int) oneO;
int newOneOne = (int) oneOneO;
Console.WriteLine(newOne == newOneOne); // true
If you would use Equals
instead of ==
they would also be compared as expected because System.Int32
overrides Equals
meaningfully.
old
and Oldold
are reference types(string) which are not boxed, only value types
- But string is a special reference type which overloads the equality operator(read further)
As a rule of thumb: if you use reference types be careful with the ==
operator. System.String
overloads the equality operator for example. But that is an exception. Normally you are just comparing references. Boxing basically makes the value type a reference type, but that's a hidden implementation detail(even oneO.GetType().IsValueType
still returns true
).
Also note that this boxing conversion also takes place if you have a method like this:
public static bool SameThings(object obj1, object obj2)
{
return obj1 == obj2;
}
I hope you are not anymore surprised that this outputs false
:
Console.WriteLine(SameThings(1, 1)); // false