zoukankan      html  css  js  c++  java
  • .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将在下一篇文章中讲解。

  • 相关阅读:
    Linux 远程和本地的一些解决方式
    【Android界面实现】使用PagerTabStrip实现有滑动标签的Viewpager
    Elasticsearch
    Awk使用及站点日志分析
    我的软考之路(八)——三大原则学会数据流图
    BZOJ 3864 Hero meet devil DP套DP
    Android studio 自己定义打包APK名称
    C/C++——程序的内存分配
    剑指offer 高速排序
    HDU1069(还是dp基础)
  • 原文地址:https://www.cnblogs.com/accessking/p/2923424.html
Copyright © 2011-2022 走看看