• 委托及观察者模式


    委托

    委托(delegate)是一种特殊的类型(class),它可以被认为是一个可以拥有函数引用的类,它的声明规定了它能够持有的函数引用的函数形式,同时它可以存储多个函数引用,并通过自己的方法调用所有注册在它身上的方法(发布者)。

    理解了观察者模式就理解了委托

    它的特点在于:

    1. 委托类型的定义方式通过特定关键字 delegate 来定义,而不是 class

    image

    1. 我们无法为委托类型定义方法,它继承固定的类有固定的方法,这是发生在语言底层的

    image

    1. 一个委托类型的变量时可以像一个普通类型的变量一样声明,但更好的方式是使用 event 关键字来修饰委托类型的变量,event 关键字包装了委托类型的变量(事件变量不是委托变量,它们是两个东西,尽管它们在声明方式上很像,事件变量包装了一个委托变量),这将避免从类外控制这个事件的发布(Invoke
    namespace InterfaceTest
    {
        [TestClass]
        public class DelegateTest
        {
            // 一个自定义的委托类型的变量,类比自定义的类的变量
            public event Function calc;
    
            [TestMethod]
            public void TestMethod1()
            {
                calc += () =>
                {
                    return 0.0;
                };
                calc += DelegateTest.C;
                calc += new Function(C);
                calc = calc + C;
                calc.Invoke();
            }
    
            public static double C() { return 1.0;  }
        }
    
        // 委托是一个类型,所以它可以直接定义在名称空间下
        // 无法为委托类型自定义方法
        public delegate double Function();
    
        public class Caller
        {
            public Caller()
            {
                var dt = new DelegateTest();
                // 由于calc是一个event修饰的属性,所以从外部调用Invoke将引发异常
                dt.calc.Invoke(); // ERROR
            }
        }
    }
    

    外部访问event报错

    1. 就像我们可以直接使用语言本身提供的 string 类型一样,我们也可以直接使用语言本身提供的 ActionFunc 委托类型,它们已经包含了绝大多数可能的函数签名的形式,而无需自定义自己的 “MyString”

    委托及观察者模式

    image

    在观察者模式中主要有四个事物:发布者、订阅者、“订阅”过程、“发布”过程。

    发布者主要包含一个保存了订阅者引用的集合,在“发布过程”发生时,通过这个订阅者所持有的引用调用实现了相同接口的订阅者的方法(在这一步有多种方式,不一定非要是接口,目的在于使发布者能够通过多态统一保存所有的订阅者,从而在“发布”时遍历整个集合调用所有订阅者的方法。关于其它的实现方式可见引用.6)。

    在委托中,观察者模式的这四个部分的实现如下:

    • 发布者:委托类型的变量

    • 订阅者:符合委托类型定义的函数签名的函数,表现形式有lambda表达式、直接定义的函数等(将函数当作一个函数类型的实例)

    • “订阅”:+ -,常见的形式是 += -=,本质上是委托类型重载了 +- 运算符

    • “发布”:

      1. 由系统负责“发布”,程序员提供发布时的动作(委托类型的函数):例如,WPF或Winform后置代码中的事件响应函数

      2. 由程序员负责“发布”,系统负责提供发布时的动作:例如,WPF中的OnPropertyChanged 在ViewModel中手动调用,但它上的函数的注册在XAML解析时完成

    引用

    1. 《C#图解教程》
    2. 刘铁猛. C#语言入门详解
    3. learn.microsoft 如何组合委托
    4. MulticastDelegate.cs
    5. Delegate.cs
    6. 观察者模式
  • 相关阅读:
    总结:协程与线程
    Java多线程总结:进程与线程、线程的创建、线程状态与分类、线程方法、线程同步
    【力扣】83. 删除排序链表中的重复元素
    2021 CSP J2入门组 CSP-S2提高组 第2轮 视频与题解
    Python中的self与类的理解
    javaweb springboot餐厅点餐系统源码
    共模电感选择请收好谷景电感教你的小方法
    使用Kali Linux Metasploit 对WEB应用进行攻击 以DVWA为例
    virtualbox基本配置
    你入职的时候一定要问领导要的maven私服配置文件,它是什么?Nexus入门使用指南
  • 原文地址:https://www.cnblogs.com/bblitz/p/17502704.html