能说说C#委托的基本原理是啥吗?

委托这个概念对C++程序员来说并不陌生,因为它和C++中的函数指针非常类似,很多码农也喜欢称委托为安全的函数指针。无论这一说法是否正确,委托的的确确实现了和函数指针类似的功能,那就是提供了程序回调指定方法的机制.

在委托内部,包含了一个指向某个方法的指针(这一点上委托实现机制和C++的函数指针一致),为何称其为安全的呢?因为委托和其他.NET成员一样是一种类型,任何委托对象都是继承自System.Delegate的某个派生类的一个对象,下图展示了在.NET中委托的类结构:

能说说C#委托的基本原理是啥吗?

从上图也可以看出,任何自定义的委托都继承自基类 System.Delegate,在这个类中,定义了大部分委托的特性。那么,下面可以看看在.NET中如何使用委托:

// 定义的一个委托
public delegate void TestDelegate(int i);
public class Program
{
    public static void Main(string[] args)
    {
        // 定义委托实例
        TestDelegate td = new TestDelegate(PrintMessage);
        // 调用委托方法
        td(0);
        td.Invoke(1);
        Console.ReadKey();
    }
    public static void PrintMessage(int i)
    {
        Console.WriteLine("这是第{0}个方法!", i.ToString());
    }
}

运行结果如下图所示:

能说说C#委托的基本原理是啥吗?

上述代码中定义了一个名为TestDelegate的新类型,该类型直接继承自 System.MulticastDelegate,而且其中会包含一个名为Invoke、BeginInvoke和EndInvoke的方法,这些步骤都是由C#编译器自动帮我们完成的,可以通过Reflector验证一下如下图所示:

能说说C#委托的基本原理是啥吗?

需要注意的是,委托既可以接受实例方法,也可以接受静态方法(如上述代码中接受的就是静态方法),其区别我们在1.2中详细道来。最后,委托被调用执行时,C#编译器可以接收一种简化程序员设计的语法,例如上述代码中的:td(1)。但是,本质上,委托的调用其实就是执行了在定义委托时所生成的Invoke方法。