zoukankan      html  css  js  c++  java
  • 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(); ,这样是为了调用者不能想调用就调用。为了防止当触发一个件事,执行到一部分的时候就来调用。

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

  • 相关阅读:
    Transact_SQL小手册
    使用泛型的 TArray 从动态数组中查找指定元素
    使用泛型的 TArray 为动态数组排序
    使用 InputBox、InputQuery 的启发
    近况汇报
    泛型排序器 TComparer
    详测 Generics Collections TList (2): First、Last、IndexOf、LastIndexOf
    详测 Generics Collections TList (1): Add、Clear、Count、Capacity
    WindowsAPI: MulDiv
    SendTextMessage 等方便的消息发送函数
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/8721332.html
Copyright © 2011-2022 走看看