2

Objects comparison after using reflection

var a = new A
   {
      a = "aa",
      b = 1
   };

   var b = new A { 
      a = "aa",
      b = 2
   };

   Type type = typeof(A);

   object old = type.GetProperty("a").GetValue(a);
   object Oldold = type.GetProperty("a").GetValue(b);

   int one = 1;
   int oneOne = 1;

   object oneO = one;
   object oneOneO = oneOne


   // old == Oldold  - true
   // one == oneOne - true
   // oneO == oneOneO - false
}

I would expect that oneO == oneOneO is true. Can someone explain me what is going on here?

Pawel
  • 525
  • 3
  • 16
  • From [MSDN](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators) **By default, two reference-type operands are equal if they refer to the same object:** – styx Jul 17 '19 at 11:04

1 Answers1

4

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
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Also could use `.Equals()` instead of == without unboxing – styx Jul 17 '19 at 11:08
  • Ok, thanks :) That was a warm up. After digging a little bit more in reflection comparisons I have faced another problem: https://stackoverflow.com/questions/57078896/operator-when-comparing-object-properties-using-reflection – Pawel Jul 17 '19 at 15:02