自学内容网 自学内容网

【超详细】C#事件

目录

事件

1.定义

2.特点

观察者模式

定义

重要概念

3.使用步骤(重点)

4.使用场景

5.优势

6.限制

7.举例

7.1.猫叫,鼠跑人醒。

7.2.老鹰冲下来,小鸡逃跑,狗叫。


       事件是一种特殊的委托,那什么是委托呢?简而言之,委托是一种数据类型(关键字delegate);委托代表的是方法;当调用委托时就是调用了这个方法。想要进一步了解委托,可以参考【一文了解】C#重点-委托1【一文了解】C#重点-委托2了解委托的定义、3个基本使用步骤、单播委托和多播委托、实例化委托的四种方法。

事件

1.定义

       事件(event)是声明为委托类型的类的成员,允许一个类或对象通知其他类或对象某个特定的事情已经发生。事件基于委托。表示类的偶发行为,一旦这个行为发生,往往要引起其他行为/方法发自动执行。事件是用来实现两个或多个行为的联动调用的。简而言之,事件(关键字event)是声明为委托类型的类的成员变量,是一种特殊的委托。

2.特点

       事件发生后,其他对象做出响应。事件是一种观察者模式的实现方式。

观察者模式

定义

       一个对象(被观察者)维护一组依赖于它的对象(观察者)。当被观察者的状态发生变化时,所有的观察者都会被通知并作出相应的反应。通过这种方式,观察者模式实现了松耦合的设计,使得事件源和响应者之间不需要直接依赖彼此。

重要概念

1)事件源(被观察者):定义事件,并负责触发事件。
2)响应者(观察者):订阅事件,并响应事件。

如:张三骂李四,李四打张三 (事件源:张三,响应者:李四)

3.使用步骤(重点)

       步骤严格固定定义端①③ 调用端②④

①声明事件

       首先要定义一个委托,该委托定义了事件处理程序的签名(返回类型和参数列表)

public delegate void MyEventHandler(object sender, EventArgs e);

       然后在类中声明事件

public event 委托类型 事件名;

②注册事件

写法1(传统写法):事件源对象.事件 += new 委托类型(响应方法)

写法2(简化写法):事件源对象.事件 += 响应方法

注意: += 注册/订阅事件-= 取消注册/退订事件

③触发事件

       事件会在类的某个方法中触发。为了触发事件,需要使用Invoke方法,但为了防止在没有订阅者时引发 NullReferenceException,一般使用?.Invoke()。

④调用包含触发事件的方法

处理思路:

       首先要思考当前问题是否需要使用事件(分析行为是否有联动性),即是否行为1发生后行为2会跟着发生?如果还是不能理解,那可以将事件的处理做为一种因果关系来加以理解。

1)因:事件触发

事件的触发是一个原因,它可以由发布者(事件源)内部的某些操作或状态变化引发。

如,在用户界面中,当用户点击关闭按钮(因),会导致按钮的点击事件被触发。

2)果:事件处理

事件处理方法的执行是结果,即订阅者(响应者)在事件被触发时执行的操作。

如,当按钮的点击事件被触发,事件处理方法被执行,窗口关闭(果)。

       总结:事件源(发布者)负责触发事件。响应者(订阅者)负责处理事件。事件的目的是用来解决联动性的问题,主要功能是进行通知。

4.使用场景

       在GUI开发中,当用户点击按钮时,按钮会触发点击事件,其他对象可以订阅该事件并执行相应的操作。

       在多线程编程中,一个线程可以触发事件通知其他线程某些状态的变化。

       在游戏开发中,当角色的状态发生变化(如生命值变化、位置变化),可以触发相应的事件,让其他对象做出响应。

5.优势

①解耦:事件允许发布者和订阅者之间的解耦,发布者不需要知道谁订阅了事件,订阅者也不需要知道事件是如何触发的,只需要关注自己的处理逻辑。

②封装:事件只能在声明事件的类中触发,外部类只能订阅或取消订阅,保证了封装性和安全性,防止外部代码意外触发事件。

③多播:事件可以是多播的,即可以有多个订阅者,当事件触发时,所有订阅者的处理程序会依次调用。

6.限制

       事件只能在声明的类中触发,外部类无法直接触发或修改事件,只能订阅或取消订阅。

       事件一般用于通知,不建议在事件处理程序中返回值,因为多个订阅者的情况下,无法处理多个返回值。

7.举例

       下面我们来通过案例来加以理解。

7.1.猫叫,鼠跑人醒。

分析:

①找到行为:叫,跑,醒

②分析行为是否有联动性,可以从案例看出行为有联动性,因为猫叫了,所以老鼠跑了,主人惊醒了。接着分析,原因(叫)的行为作为事件,结果(跑,醒)的行为作为普通方法。然后根据事件的使用步骤来完成案例

using UnityEngine;

namespace EventTest
{
    //猫叫,鼠跑人醒
    //调用端
    public class CatEvent : MonoBehaviour
    {
        private void Start()
        {
            Mouse mouse = new Mouse();
            Host host = new Host();
            //②注册事件
            //事件源:因                 响应方法:果
            //写法1:传统方法
            //事件源对象.事件+=new 委托类型(响应方法);
            Cat cat = new Cat();
            cat.MiaoMiao += new CatHandler(mouse.Run);
            //写法2:简化写法
            //事件源对象.事件+=响应方法;
            cat.MiaoMiao += host.Awake;
            //④调用触发事件的方法
            cat.Notify();
        }
    }
    //定义端
    //①定义事件
    //先定义委托,委托代表的是方法,调用委托就是调用方法
    public delegate void CatHandler();
    class Cat
    {
        //再定义事件,事件是类中为委托类型的成员
        public event CatHandler MiaoMiao;
        public void Notify()
        {
            Debug.Log("猫:Miao miao~");
            //③触发事件
            MiaoMiao?.Invoke();
        }
    }
    //3)响应方法
    class Mouse
    {
        public void Run()
        {
            Debug.Log("老鼠:逃跑");
        }
    }
    class Host
    {
        public void Awake()
        {
            Debug.Log("主人:惊醒");
        }
    }
}

       输出结果:

7.2.老鹰冲下来,小鸡逃跑,狗叫。

分析:

①找到行为:冲,跑,叫

②分析行为是否有联动性,可以从案例看出行为有联动性,因为猫叫了,所以老鹰冲下来,所以小鸡逃跑,狗叫。接着分析,原因(叫)的行为作为事件,结果(跑,醒)的行为作为普通方法。然后根据事件的使用步骤来完成案例。

using UnityEngine;

namespace EventTest
{
    //老鹰冲下来,小鸡逃跑,狗叫
    //调用端
    public class EagleEvent : MonoBehaviour
    {
        private void Start()
        {
            Chick chick = new Chick();
            Dog dog = new Dog();
            Eagle eagle = new Eagle();
            //②注册事件 
            //事件源:因                 响应方法:果
            //写法1:传统方法
            //事件源对象.事件+=new 委托类型(响应方法);
            eagle.Swoop += new EagleSwoopHandler(chick.Run);
            //写法2:简化写法
            //事件源对象.事件+=响应方法;
            eagle.Swoop += dog.WangWang;
            //④调用触发事件的方法
            eagle.Notify();
        }
    }
    //定义端
    //①定义事件
    //定义委托 委托代表的是方法,调用委托就是调用方法
    public delegate void EagleSwoopHandler();
    class Eagle
    {
        //①定义事件
        public event EagleSwoopHandler Swoop;
        public void Notify()
        {
            Debug.Log("老鹰:冲下来");
            //③触发事件
            Swoop?.Invoke();
        }
    }
    //响应方法
    class Chick
    {
        public void Run()
        {
            Debug.Log("小鸡:逃跑");
        }
    }
    class Dog
    {
        public void WangWang()
        {
            Debug.Log("小狗:Wang wang~");
        }
    }
}

       输出结果:

       好了,本次的分享到这里就结束啦,希望对你有所帮助~


原文地址:https://blog.csdn.net/grapefruit_lyy/article/details/145285593

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!