• c#之委托事件(DelegateEvent)


    前面一章学习了委托以及多播委托,接下来我们来学习下委托事件。

    在学习委托事件的前提下,得知道什么是观察者模式。

    首先,我们来模拟一个场景:例如,当一只狗汪汪汪叫的时候,baby被吓哭了,刚好要偷东西的小偷被吓跑了。

    我们一惯的思维是:创建三个类,分别写一个方法表示他们的动作,当狗叫的时候,分别调用。代码如下:

        public class Dog
        {
            public static void Wang() 
            {
                Console.WriteLine("狗汪汪汪汪");
                Baby.Cry();
                Thief.Run();
            }
        }
        public class Baby
        {
            public static void Cry() 
            {
                Console.WriteLine("baby被吓哭了");
            }
        }
        public class Thief
        {
            public static void Run() 
            {
                Console.WriteLine("小偷跑了");
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Dog.Wang();
    
                Console.Read();
            }
        }

    这样做是可以得到我们想要的结果,但是,Dog类与Baby、Thief之间的耦合就很紧了,不利于后期维护扩展。当我们后期需求变动,要再添加一个动作:猫也被吓的跑掉了。

    怎么办,难道我们还要去改动Dog类里Wang方法的代码嘛?这明显是一个糟糕的事情。不过总是有办法解决的,毕竟办法都是人想出来的。

    上一个章节我们知道了多播委托,就是把多个方法绑定到同一个委托,然后依次执行。

    接下来我们来看看怎么实现。

    1、首先我们得声明一个委托,并且创建这个委托的实例。

    2、当狗叫的时候,我们来调用这个委托。

    3、当我们调用狗叫之前,将要触发的一系列动作(也就是观察者的动作)绑定到委托就行了。

    这3个步骤的代码如下:

        public delegate  void DogWang();
        public class Dog
        {
            static DogWang DogWangHandler;
            public static void Wang() 
            {
                Console.WriteLine("狗汪汪汪汪");
    
                if (DogWangHandler != null)
                    DogWangHandler.Invoke();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Dog.DogWangHandler = new DogWang(Baby.Cry);
                Dog.DogWangHandler += Thief.Run;
    
                Dog.Wang();
    
                Console.Read();
            }
        }

    贴一下结果吧。

    没毛病。讲到这里,恍然大悟了,这样的话,我们后需求添加多少个动作都没关系,我们只需要将方法绑定(+=)给委托就行。当然也是可以取消(-=)某一个动作的。

    接下来我们就要开始讲事件了,

    那么什么是事件呢?什么是委托呢,它们之前又是什么关系呢?我想这个问题肯定有很多人想知道,也有很多人搞不清楚。

    我们知道委托是一种类型,而事件就是委托一个实例 。其实就是这么简单的。

    我们将上面的代码用事件来实现,看看是什么样的。

        public delegate  void DogWang();
        public class Dog
        {
            public static DogWang DogWangHandler;
            public static event DogWang DogWangHandlerEvent;//事件的本质就是委托的一个实例。加了event关键字
            public static void Wang() 
            {
                Console.WriteLine("狗汪汪汪汪");
    
                if (DogWangHandlerEvent != null)
                    DogWangHandlerEvent.Invoke();
            }
        }
    
    class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("==============事件实现================");
                Dog.DogWangHandlerEvent += Baby.Cry;
                Dog.DogWangHandlerEvent += Thief.Run;
                Dog.Wang();
    
                Console.Read();
            }
        }

    结果如下:

    结果和上面一样,这是就委托事件。那么委托与事件调用有什么不一样呢?

    1、事件不能像委托一样 Dog.DogWangHandler = new DogWang(Baby.Cry); 被这样初始化。因为委托可以 Dog.DogWangHandler = null; ,用事件是为了不能在外部随随便便地将委托给 null 。

    2、事件不能像委托一样在外部调用 Dog.DogWangHandler(); ,这样是为了调用者不能想调用就调用。为了防止当触发一个件事,执行到一部分的时候就来调用。

    小结一下:其实它们之前的区别就是一个权限问题。

  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/8721332.html
Copyright © 2020-2023  润新知