详细探讨delegate(委托)和event(事件)(2)

delegate(2)

 

上一篇我们看了委托的概念和例子,相信很多人都会想,委托是怎么实现的?VS自带的工具ILDASM,可以查看一个exe或者dll文件的IL代码,具体方法是进入Visual Studio Tools 下的 Visual Studio Command Prompt命令行,输入ILDASM就能看到一个可视化的界面,执行File-->Open,可以选择一个exe文件,比如打开上一篇(http://canbeatle.iteye.com/admin/blogs/686138)中的程序生成的exe文件,可以看到这样的结构:

 

 详细探讨delegate(委托)和event(事件)(2)_第1张图片

 

这些内容其实很简单,注意上图中我加的图标的说明,可以看到TestMathClass中的delegate在IL中是一个class,名称为Operation,就是委托的名称,该class拥有4个method,除了构造函数外,分别是BeginInvoke, EndInvoke, Invoke,其中Invoke的签名和delegate的签名是完全一样的,是不是调用委托方法的时候就是执行的Invoke呢?

 

在我的例子中,委托是在Main函数中赋值和调用的,为了查看具体的实现,我们双击TestMathClass中的Main:void 函数,看看它的具体实现是怎么样的:

 

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       100 (0x64)
  .maxstack  3
  .locals init ([0] class EventDelegateTest.TestMathClass/Operation operation,
           [1] int64 sum,
           [2] int64 product)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  ldftn      int64 EventDelegateTest.MathClass::Add(int32, int32)
  IL_0008:  newobj     instance void EventDelegateTest.TestMathClass/Operation::.ctor(object,native int)
  IL_000d:  stloc.0
  IL_000e:  ldloc.0
  IL_000f:  ldc.i4.s   11
  IL_0011:  ldc.i4.s   22
  IL_0013:  callvirt   instance int64 EventDelegateTest.TestMathClass/Operation::Invoke(int32,int32)
  IL_0018:  stloc.1
  IL_0019:  ldnull
  IL_001a:  ldftn      int64 EventDelegateTest.MathClass::Multiply(int32,int32)
  IL_0020:  newobj     instance void EventDelegateTest.TestMathClass/Operation::.ctor(object,native int)
  IL_0025:  stloc.0
  IL_0026:  ldloc.0
  IL_0027:  ldc.i4.s   30
  IL_0029:  ldc.i4.s   40
  IL_002b:  callvirt   instance int64 EventDelegateTest.TestMathClass/Operation::Invoke(int32,int32)
  IL_0030:  stloc.2
  IL_0031:  ldstr      "11 + 22 = "
  IL_0036:  ldloc.1
  IL_0037:  box        [mscorlib]System.Int64
  IL_003c:  call       string [mscorlib]System.String::Concat(object, object)
  IL_0041:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0046:  nop
  IL_0047:  ldstr      "30 * 40 = "
  IL_004c:  ldloc.2
  IL_004d:  box        [mscorlib]System.Int64
  IL_0052:  call       string [mscorlib]System.String::Concat(object, object)
  IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_005c:  nop
  IL_005d:  call       string [mscorlib]System.Console::ReadLine()
  IL_0062:  pop
  IL_0063:  ret
} // end of method TestMathClass::Main

 这段IL代码我们不需要全看懂,只需注意这一段(Line15~17):

IL_000f:  ldc.i4.s   11
IL_0011:  ldc.i4.s   22
IL_0013:  callvirt   instance int64 EventDelegateTest.TestMathClass/Operation::Invoke(int32,int32)

 

首先load两个常量(ldc):11和22,然后调用TestMathClass/Operation::Invoke方法。这也证实了刚才的猜想:委托就是一个类,执行的时候就是调用其Invoke方法(BeginInvoke和EndInvoke以后再探讨)。下一篇(http://canbeatle.iteye.com/blog/686800)我将探讨event。

你可能感兴趣的:(Blog)