多播委托浅析

饮水思源

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
坑你急哇

好,这就是我们的多播委托 , 概念性的东西太难理解了.

多播委托浅析

还记得我们分析,委托原理的时候,说过的委托的继承关系吗:

自定义委托 继承自 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 工具,往深处研究,这里就不在赘述。毕竟笔者水平也有限。

转载于:https://www.cnblogs.com/slyfox/p/7512355.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值