zoukankan      html  css  js  c++  java
  • .NET对象判等(一)

    对于一般的对象来说有判断是否和另一个对象是否相等,有四种方式。

    1、Object.ReferenceEquals(static)

    2、Object.Equals(static)

    3、Instance.Equals

    4、Operator ==

    一、ReferenceEquals追本溯源

    MSDN官方解释:确定指定的 Object 实例是否是相同的实例。 

    尽管MSDN的解释很简练,到位.但是我仍然通过ILDASM,.NET Reflector 来查看一下ReferenceEquals的实现方式.

    .method public hidebysig static bool  ReferenceEquals(object objA,
                                                          object objB) cil managed
    {
      .custom instance void System.Runtime.ConstrainedExecution.ReliabilityContractAttribute::.ctor(valuetype System.Runtime.ConstrainedExecution.Consistency,
                                                                                                    valuetype System.Runtime.ConstrainedExecution.Cer) = ( 01 00 03 00 00 00 02 00 00 00 00 00 ) 
      // 代码大小       5 (0x5)
      .maxstack  8
      IL_0000:  ldarg.0 //将索引为 0 的参数加载到计算堆栈上。
      IL_0001:  ldarg.1 //将索引为 1 的参数加载到计算堆栈上。
      IL_0002:  ceq 
      IL_0004:  ret
    } // end of method Object::ReferenceEquals

    指令CEQ的MSDN官方解释是:比较两个值。如果这两个值相等,则将整数值 1 (int32) 推送到计算堆栈上;否则,将 0 (int32) 推送到计算堆栈上。

    这里的“值”实在是大可商榷,据鄙人目测是实例存储在托管堆上的地址,即实例引用(指针)的实际值。

    值得注意的是使用Object.ReferenceEquals对值类型变量进行判等,Reshaper会做出提示:'Object.ReferenceEquals‘ 总是返回False

    实际上比较两个值类型变量实际与通过此方法对引用类型变量判等是大同小异的,首先看一下ReferenceEqual的方法签名及方法体,如下:

     1 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
     2 
     3 public static bool ReferenceEquals(object objA, object objB)
     4 {
     5     return (objA == objB);
     6 }

    虽然传入的是值类型变量,但方法体内操作的是引用类型变量,在传参的过程中,CLR对a和b分别进行了封装,获得了存储在GC堆上的两个实例objA和objB,这时候再套用Object.ReferenceEquals对引用变量判等的就可以了。

    二、Static Object.Equals

    通过.NET Reflector获得Object Equals的实现Code:

    1 public static bool Equals(object objA, object objB)
    2 {
    3     return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
    4 }

    对于Object.Equals我不想讨论过多,因为它把大部分工作都托管给了Operator ==以及Instance.Equals。同时Object.Equals提供了一种良好的对象判等方式。

  • 相关阅读:
    SqlServer2008 / SqlServer2012 禁用windows登录,sa忘记密码或密码过期如何登陆
    windows下批处理保留指定日期下的文件
    centos7上使用git clone出现问题
    VS2015编译Teamtalk的Windows客户端(转)
    Mac Book触摸板失灵的解决办法(触摸板按下失灵)
    系统设计原则
    命令“regsvr32 /s /n /i:user "XXXXXX"”已退出,代码为 3
    Android实现开机自动运行程序
    Java并发之CyclicBarrier、CountDownLatch、Phaser
    Java多线程之ThreadLocal
  • 原文地址:https://www.cnblogs.com/accessking/p/2922601.html
Copyright © 2011-2022 走看看