【IT168 技术】我本来以为委托很简单,本来只想简简单单的说说委托背后的东西,委托的使用方法。原本只想解释一下那句:委托是面向对象的、类型安全的函数指针。可没想到最后惹出一堆的事情来,越惹越多,罪过,罪过。本文后面一部分是我在一边用SOS探索一边记录的,写的非常糟糕,希望您的慧眼能发现一些有价值的东西,那我就感到无比的荣幸了。
委托前世与今生
大家可能还记得,在C/C++里,我们可以在一个函数里实现一个算法的骨架,然后在这个函数的参数里放一个“钩子”,使用的时候,利用这个“钩子”注入一个函数,注入的函数实现不同算法的不同部分,这样就可以达到算法骨架重用的目的。而这里所谓的“钩子”就是“函数指针”。这个功能很强大啊,但是函数指针却有它的劣势:不是类型安全的、只能“钩”一个函数。大家可能都知道微软对委托的描述:委托是一种面向对象的,类型安全的,可以多播的函数指针。要理解这句话,我们先来看看用C#的关键字delegate声明的一个委托到底是什么样的东西:
namespace Yuyijq.DotNet.Chapter2
{
public delegate void MyDelegate(int para);
}
{
public delegate void MyDelegate(int para);
}
隐藏在背后的秘密
很简单的代码吧,使用ILDasm反编译一下:
图1 使用ILDasm反编译
奇怪的是,这么简单的一行代码,变成了一个类:类名与委托名一致,这个类继承自System.MulticastDelegate类,连构造器一起有四个成员。看看我们如何使用这个委托:
public class TestDelegate
{
MyDelegate myDelegate;
public void AssignDelegate()
{
this.myDelegate = new MyDelegate(Test);
}
public void Test(int para)
{
Console.WriteLine("Test Delegate");
}
}
{
MyDelegate myDelegate;
public void AssignDelegate()
{
this.myDelegate = new MyDelegate(Test);
}
public void Test(int para)
{
Console.WriteLine("Test Delegate");
}
}
编译后用ILDasm看看结果:
.field private class Yuyijq.DotNet.Chapter2.MyDelegate myDelegate
发现,.Net把委托就当做一个类型,与其他类型一样对待,现在你明白了上面那句话中说委托是面向对象的函数指针的意思了吧。