zoukankan      html  css  js  c++  java
  • 多播委托浅析

    饮水思源

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

  • 相关阅读:
    HTML DOM教程 14HTML DOM Document 对象
    HTML DOM教程 19HTML DOM Button 对象
    HTML DOM教程 22HTML DOM Form 对象
    HTML DOM教程 16HTML DOM Area 对象
    ubuntu 11.04 问题 小结
    VC6.0的 错误解决办法 小结
    boot.img的解包与打包
    shell里 截取字符串
    从零 使用vc
    Imagemagick 对图片 大小 和 格式的 调整
  • 原文地址:https://www.cnblogs.com/slyfox/p/7512355.html
Copyright © 2011-2022 走看看