• .NET对象判等(二)


    .NET对象的几种判等,耦合在一起,我尽量在任意一种判等里不涉及其他判等方式。但是Instace.Equals仍然不法避免不使用到Operator ==,所以我把Operator ==作为第三部分内容。

    三、Operator==深入本质

    默认情况下,Operator==在对引用类型对象判等的本质和Object.ReferenceEquals是相同的即确定指定的变量是否是相同的实例。

    当然C#.NET可对Opeartor==进行定义,鄙人认为应该避免自定义Operator==。任意定义将会对使用者对Opeartor==的作用产生混淆。毕竟没有任何逻辑比a=a更有逻辑了。

    对于自描述值类型来说如果想使用Operator==进行判等,那么就要对Opeartor==以及Opeartor!=分别进行定义。FCL的大部分值类型都是这样做的比如DateTime、Decimal等。

    存在这样的情况Int32、Int64、Byte等值类型并未定义Opeartor==,但是编译器仍然支持以上类型变量直接使用Operator==进行判等。同查阅相关资料得知包括byte、shrot、 int、long、char、float、double、bool、decimal、string、object、dynamic共十二种类型为基元类型。编译器直接支持的数据类型称为基元类型。基元类型直接映射到Framework类库(FCL)中存在的类型。比如在C#中,int直接映射到System.Int32类型。

    当两个int类型变量进行判等,首先将两个值压入计算堆栈,CLR通过CEQ指令直接对值进行判等。当然基元类型是支持定义Opeartor的比如Decimal就定义了Opeartor==。

    有趣的是,sbyte、ushort、uint、ulong并非基元类型,也未定义Opeartor,但是以上几种类型直接使用Opeartor==判等,CSC编译器仍然能够编译通过。以ushort为例,请看一下代码:

    1 static void Main()
    2 { 
    3       ushort u1=1;
    4       ushort u2 = 2;
    5       var b = u1 == u2;
    6  }

    通过ILDASM反编译,得到的IL代码

     1 .method private hidebysig static void  Main() cil managed
     2 {
     3   .entrypoint
     4   // 代码大小       11 (0xb)
     5   .maxstack  2
     6   .locals init (uint16 V_0,
     7            uint16 V_1,
     8            bool V_2)
     9   IL_0000:  nop
    10   IL_0001:  ldc.i4.1 //将整数值 1 作为 int32 推送到计算堆栈上。                               
    12   IL_0002:  stloc.0  //从计算堆栈的顶部弹出当前值并将其存储到索引 0处的局部变量列表中。 
    13   IL_0003:  ldc.i4.2 //将整数值 2 作为 int32 推送到计算堆栈上。
    15   IL_0004:  stloc.1  //同上,存储到索引1处的局部变量列表
    16   IL_0005:  ldloc.0  //将索引 0 处的局部变量加载到计算堆栈上。
    17   IL_0006:  ldloc.1  //同上
    18   IL_0007:  ceq      //如果这两个值相等,则将整数值 1 (int32) 推送到计算堆栈上;否则,将 0 (int32) 推送到计算堆栈上。
    19   IL_0009:  stloc.2  //同上
    20   IL_000a:  ret
    21 } // end of method Program::Main

    代码中添加了一部分注释,大概的意思就是将ushort隐身的看作int类型,在通过CEQ指令对基元类型进行判等,类似于以下代码:

    1 static void Main()
    2  { 
    3       int i1 = 1;
    4       int i2 = 2;
    5       var b = i1 == i2;
    6  }

    关于Instance.Equals将在下一篇文章中讲解。

  • 相关阅读:
    java private修饰的类和变量
    Volatile和Synchronized对可见性和原子性的支持
    Socket套接字
    Spring MVC请求执行流程
    Spring AOP术语解释
    equals()和==的区别
    约瑟夫环之递归算法
    数据库特性之原子性和一致性
    设计模式之单例模式
    平衡二叉树的插入旋转
  • 原文地址:https://www.cnblogs.com/accessking/p/2923424.html
Copyright © 2020-2023  润新知