IL查看委托
查看委托的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来认识和使用委托 (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |