首页 > 解决方案 > == 运算符使用反射

问题描述

使用反射后的对象比较

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
}

我希望 oneO == oneOneO 是真的。有人可以解释一下这里发生了什么吗?

标签: c#reflection

解决方案


您通过将其分配给变量来装箱。这会创建一个新实例并在比较引用时,它们是不同的,所以它返回.intObject==System.Objectfalse

如果您将其转换回(取消装箱)到int将按==预期工作:

object oneO = one;
object oneOneO = oneOne;
int newOne = (int) oneO;
int newOneOne = (int) oneOneO;
Console.WriteLine(newOne == newOneOne); // true

如果您使用Equals而不是它们,==它们也将按预期进行比较,因为有意义地System.Int32 覆盖。Equals

  • old并且Oldold是没有装箱的引用类型(字符串),只有值类型
  • 但是字符串是一种特殊的引用类型,它重载了相等运算符(进一步阅读)

根据经验:如果您使用引用类型,请小心==操作符。System.String 例如,重载相等运算符。但那是个例外。通常你只是比较参考。装箱基本上使值类型成为引用类型,但这是一个隐藏的实现细节(甚至oneO.GetType().IsValueType仍然返回true)。

另请注意,如果您有这样的方法,也会发生这种装箱转换:

public static bool SameThings(object obj1, object obj2)
{
    return obj1 == obj2;
}

我希望您不再对此输出感到惊讶false

Console.WriteLine(SameThings(1, 1));  // false

推荐阅读