能说说什么是C#链式委托吗?

链式委托也被称为“多播委托”,其本质是一个由多个委托组成的链表。回顾上面1.2中的类结构,System.MulticastDelegate 类便是为链式委托而设计的。当两个及以上的委托被链接到一个委托链时,调用头部的委托将导致该链上的所有委托方法都被执行。.

下面看看在.NET中,如何申明一个链式委托:

// 定义的一个委托
public delegate void TestMulticastDelegate();
public class Program
{
    public static void Main(string[] args)
    {
        // 申明委托并绑定第一个方法
        TestMulticastDelegate tmd = new TestMulticastDelegate(PrintMessage1);
        // 绑定第二个方法
        tmd += new TestMulticastDelegate(PrintMessage2);
        // 绑定第三个方法
        tmd += new TestMulticastDelegate(PrintMessage3);
        // 调用委托
        tmd();

        Console.ReadKey();
    }
    public static void PrintMessage1()
    {
        Console.WriteLine("调用第1个PrintMessage方法");
    }
    public static void PrintMessage2()
    {
        Console.WriteLine("调用第2个PrintMessage方法");
    }
    public static void PrintMessage3()
    {
        Console.WriteLine("调用第3个PrintMessage方法");
    }
}

其运行结果如下图所示:

能说说什么是C#链式委托吗?

可以看到,调用头部的委托导致了所有委托方法的执行。通过前面的分析我们也可以知道:为委托+=增加方法以及为委托-=移除方法让我们看起来像是委托被修改了,其实它们并没有被修改。事实上,委托是恒定的在为委托增加和移除方法时实际发生的是创建了一个新的委托,其调用列表是增加和移除后的方法结果

能说说什么是C#链式委托吗?

另一方面,+= 或-= 这是一种简单明了的写法,回想在WindowsForm或者ASP.NET WebForms开发时,当添加一个按钮事件,VS便会自动为我们生成类似的代码,这样一想是不是又很熟悉了。

现在,我们再用一种更简单明了的方法来写:

TestMulticastDelegate tmd = PrintMessage1;
tmd += PrintMessage2;
tmd += PrintMessage3;
tmd();

其执行结果与上图一致,只不过C#编译器的智能化已经可以帮我们省略了很多代码。

最后,我们要用一种比较复杂的方法来写,但是却是链式委托的核心所在:

TestMulticastDelegate tmd1 = new  TestMulticastDelegate(PrintMessage1);
TestMulticastDelegate tmd2 = new  TestMulticastDelegate(PrintMessage2);
TestMulticastDelegate tmd3 = new  TestMulticastDelegate(PrintMessage3);
// 核心本质:将三个委托串联起来
TestMulticastDelegate tmd = tmd1 + tmd2 + tmd3;
tmd.Invoke();

我们在实际开发中经常使用第二种方法,但是却不能不了解方法三,它是链式委托的本质所在。