饮水思源
http://www.cnblogs.com/huashanlin/archive/2008/03/11/1100870.html
Overview
本文主要,来学习一下,
多播委托
, 这个名词可能比较生僻一点,通过语言很难表达出来,下面我们还是通过代码来说明吧,我本身对这些概念性的东西,就不太感冒...露怯了。多播委托
- 一个委托对象,包含一个以上的方法被称为多播委托。
Demo
一个简单的委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnderstandDelegate
{
public delegate void SayHelloHandler();
}
Person类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnderstandDelegate
{
public class Person
{
public void SayHello(SayHelloHandler handler)
{
handler.Invoke();
}
}
}
调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnderstandDelegate
{
class Program
{
static void Main(string[] args)
{
//想不到还有这种操作吧
SayHelloHandler handler = ChinaStyleSayHello;
handler += EnglishStyleSayHello;
handler += JapanStyleSayHello;
new Person().SayHello(handler);
}
static void ChinaStyleSayHello()
{
Console.WriteLine("你好");
}
static void EnglishStyleSayHello()
{
Console.WriteLine("Hello");
}
static void JapanStyleSayHello()
{
Console.WriteLine("坑你急哇");
}
}
}
输出结果
你好
Hello
坑你急哇
好,这就是我们的多播委托 ![img](file:///C:UsersITAppDataLocalTempSGPicFaceTpBq20744AC263C29.png), 概念性的东西太难理解了.
多播委托浅析
还记得我们分析,委托原理的时候,说过的委托的继承关系吗:
自定义委托 继承自 MulticastDelegate 继承自 Delegate .
现在我们来看一看
MulticastDelegate
类。
其中我们需要值得注意的方法
//移除一个委托元素从这个多播委托的tion list中。
[SecuritySafeCritical]
protected sealed override Delegate RemoveImpl(Delegate value);
//将一个该委托和一个指定的委托联合起来,产生一个新的委托对象。
[SecuritySafeCritical]
protected sealed override Delegate CombineImpl(Delegate follow);
//返回多播委托的列表,以调用的顺序排序
[SecuritySafeCritical]
public sealed override Delegate[] GetInvocationList();
看一看反编译
static void Main(string[] args)
{
//想不到还有这种操作吧
SayHelloHandler handler = ChinaStyleSayHello;
handler += EnglishStyleSayHello;
handler += JapanStyleSayHello;
new Person().SayHello(handler);
}
//被反编译为了如下代码
private static void Main(string[] args)
{
SayHelloHandler sayHelloHandler = new SayHelloHandler(Program.ChinaStyleSayHello);
sayHelloHandler = (SayHelloHandler)Delegate.Combine(sayHelloHandler, new SayHelloHandler(Program.EnglishStyleSayHello));
sayHelloHandler = (SayHelloHandler)Delegate.Combine(sayHelloHandler, new SayHelloHandler(Program.JapanStyleSayHello));
new Person().SayHello(sayHelloHandler);
}
我们的+= 运算,最后编译成了 调用Delegate.Combine 静态方法的形式,我们的编译器真是太智能了,我们来看一下Delegate.Combine 方法的源码,又用到了我们 强大又免费的
ILSpy
工具了。
public static Delegate Combine(Delegate a, Delegate b)
{
if (a == null)
{
return b;
}
//最后还是调用了我们的 MulticastDelegate类中的CombineImpl方法
return a.CombineImpl(b);
}
或许这里你可能有以为,这里不是调用的是Delegate类的方法吗? 不 请注意: Delegate 类的CombineImpl 方法是一个虚方法,
MulticastDelegate
类重写了他,因为所有的委托都遵循着这样的继承规律:自定义委托 继承自 MulticastDelegate 继承自 Delegate .在这里看着是调用的Delegate类的CombineImpl 方法,但是由于
MulticastDelegate
类重写了该方法,所以,这里本质上调用的MulticastDelegate
类的方法。
结语
本章的内容就到这里,如果还有好奇,可以继续通过我们的ILSpy
工具,往深处研究,这里就不在赘述。毕竟笔者水平也有限。