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

  • 相关阅读:
    预排序遍历树算法牺牲写性能的改进
    改造PAXOS算法消灭活锁
    扣减库存策略采用订单是否锁定库存方案
    [转]java-小技巧-001-Long序列化到前端不支持
    springboot-mybatis 批量insert
    VS2010 调试启动特别慢
    C# Winform App 获取当前路径
    DevExpress PivotGridControl控件
    (JavaScript)《JS面向对象编程指南》-- JavaScript基本数据类型、数组、循环
    (HTML5)HTML5 Web Notification桌面通知实践
  • 原文地址:https://www.cnblogs.com/slyfox/p/7512355.html
Copyright © 2011-2022 走看看