加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

IL查看委托

发布时间:2021-05-21 06:59:00 所属栏目:大数据 来源: https://www.jb51.cc
导读:查看委托的IL 通过IL来查看委托的原理, 委托示例代码 写一个委托的类如下 using System; ? namespace MyCollection { //定义一个类,该类包含两个静态方法 class IntOperations { //求整数的倍数 public void Twice( int num) { Console.WriteLine( "整数{0

查看委托的IL

通过IL来查看委托的原理,

委托示例代码

写一个委托的类如下

using System;
?
{
    //定义一个类,该类包含两个静态方法
    {
        //求整数的倍数
        {
            Console.WriteLine("整数{0}的倍数是 {1}",num,num * 2);
        }
static void Square("整数{0}的平方是 {1}n",num * num);
    }
class DelegateExample
            //实例化一个IntOperations对象
            IntOperations mo = new IntOperations();
            IntOp operations = new IntOp(mo.Twice);
            operations += new IntOp(IntOperations.Square);
            
            operations(5);
            operations(8);
            operations -= "按任意键退出...");
            Console.ReadLine(); //让屏幕暂停,以方便观察结果
}

示例解释

上面代码比较简单:首先定义了一个包含两个方法的类IntOperations,然后定义了一个委托IntOp,最后用写了一个类MainProgram来演示结果。

示例运行结果

查看IL

通过IL查看这个类的Main方法

?

IL代码

.method private hidebysig void Main(string[] args) cil managed
  .entrypoint
  // Code size       118 (0x76)
  .maxstack  3
  .locals init ([0] class MyCollection.IntOperations mo,
           [1] class MyCollection.IntOp operations)
  IL_0000:  nop
  IL_0001:  newobj     instance void MyCollection.IntOperations::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldftn      instance void MyCollection.IntOperations::Twice(int32)
  IL_000e:  newobj     instance void MyCollection.IntOp::.ctor(object,1)'>                                                               native int)
  IL_0013:  stloc.1
  IL_0014:  ldloc.1
  IL_0015:  ldnull
  IL_0016:  ldftn      void MyCollection.IntOperations::Square(int32)
  IL_001c:  newobj     instance //将一个委托对象组合到一个委托链中
  IL_0021:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,1)'>                                                                                          class [mscorlib]System.Delegate)
  IL_0026:  castclass  MyCollection.IntOp
  IL_002b:  stloc.1
  IL_002c:  ldloc.1
  IL_002d:  ldc.i4.5
  IL_002e:  callvirt   instance void MyCollection.IntOp::Invoke(int32)
  IL_0033:  nop
  IL_0034:  ldloc.1
  IL_0035:  ldc.i4.8
  IL_0036:  callvirt   instance   IL_003c:  ldloc.1
  IL_003d:  ldnull
  IL_003e:  ldftn      //从委托链上移除找到的委托对象
  IL_0049:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(  IL_004e:  castclass  MyCollection.IntOp
  IL_0053:  stloc.1
  IL_0054:  ldloc.1
  IL_0055:  ldc.i4.5
  IL_0056:  callvirt   instance   IL_005c:  ldloc.1
  IL_005d:  ldc.i4.8
  IL_005e:  callvirt   instance   IL_0064:  ldstr      bytearray (09 63 FB 4E 0F 61 2E 95 00 90 FA 51 2E 00 2E 00   // .c.N.a.....Q....
                                  2E 00 )                                           // ..
  IL_0069:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_006e:  nop
  IL_006f:  call       string [mscorlib]System.Console::ReadLine()
  IL_0074:  pop
  IL_0075:  ret
} // end of method DelegateExample::Main

IL解析

源代码中的“operations+=new IntOp(IntOperations.Square);”对应于IL代码中的IL_0021行,就是调用System.Delegate类的 Combine方法,它将一个委托对象组合到一个委托链中去(关于委托链请参见:参考文献1的P377页),委托链上增加了方法Square。不过只有相 同类型的委托才可以组合。

同理,“operations-=new IntOp(IntOperations.Square);”对应于代码IL_0049行,调用System.Delegate类的Remove方法从委 托链上移除找到的委托对象。

当然,如果把委托链上所有的方法都移出去,那么委托就没有可以调用的方法。这个时候如果你在引用这个委托的话那么肯定不能通过编译,因为编译器没有方法可以处理对象。

如果从类的角度考虑委托,那么就会容易理解一些。当然,如果你不用ILdasm反汇编一下,就看不到背后的秘密了。

所以,蔡学镛说:.Net程序员可以不会用IL Assembly写程序,但是至少要看得懂反汇编出来的IL Assembly Code。

文献资料

推荐一篇好文章:通过IL来认识和使用委托

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读