C#:事件

1、事件的本质

事件是对委托的进一步封装,本质还是委托,

事件是干嘛的:
用于对象或类间的动作协调与信息传递。

我们来这样理解:
“发生→响应”:闹钟响铃了我起床,分为五个部分
闹钟,响铃,我,起床
其中还有一个隐含的部分为:订阅     
也就是我订阅了我手机的铃声,手机响铃时,我才会发生反应。如果是别人的手机,我没有订阅,就算响铃,我也不会有反应。

事件的用处:
事件多用于桌面、手机等开发的客户端编程,因为这些程序经常是用户通过事件来“驱动”的。

2、事件的定义

event  委托类型  事件名

static void Main(string[] args)
        {
            EventDo ev = new EventDo();  
            ev._del += OpenCamera;  //订阅,+=是订阅事件的操作符
            ev.Do();  //触发这里在winform里面不需要我们来触发
            Console.ReadKey();
        }

        //具体方法的定义
        public static void OpenCamera(object sender,EventArgs e)
        {
            Console.WriteLine("我被响应了");
        }
    }

    //在winform里面,以下的操作是不需要你写的
   public class EventDo
    {
        public event EventHandler _del; //事件变量的定义
        public void Do() //调用
        {
            _del(this,new EventArgs());
        }
    }

3、为什么需要事件

为了程序的逻辑更加“有道理”,更加安全

4、事件和委托区别

1、事件只用去定义具体的方法和绑定,不需要我们调用(触发);
委托一般需要自己定义调用
2、事件不能在类外部触发,不能作为参数传递;
委托事件可以在类外部触发,可以作为参数传递
3、事件是安全的,委托在一定程度上是不安全的

5、什么时候使用事件,什么时候使用委托

事件:触发机制(某个消息发生才调用某个方法)用事件
委托:当你想传递方法参数,或者一个类想调用另一个类的方法用委托

6、事件的使用

事件的使用一般通过发布者(触发事件)和订阅者(事件对应具体方法实现)来进行。发布者会在某一条件下触发某事件,订阅者可以通过订阅该事件,来对该事件的触发做出反应

namespace 事件详细理解
{
    class Program
    {
        static void Main(string[] args)
        {
            Publisher pub = new Publisher();
            Subscriber sub = new Subscriber();

            // 1、通过事件发布器来触发事件,然后订阅器接收该事件
            pub.NumChange += new NumCountChange(sub.OnNumChange); 
            pub.InvokeEvent(); //发布者触发事件,订阅者接收该触发事件
            //pub.NumChange(14);  //事件在外部触发会报错

            // 2、通过委托则可以在外部直接触发该事件,为可行但不合理的方式
            pub.NumChangeDelegate = new NumCountChange(sub.OnNumChange);
            pub.NumChangeDelegate(200);//委托变量直接调用了订阅者的OnNumChange函数   
            Console.ReadKey();
        }
    }

    /// <summary>
    /// 声明委托类型
    /// </summary>
    /// <param name="num"></param>
    public delegate void NumCountChange(int num);

    /// <summary>
    /// 事件发布者类
    /// </summary>
    class Publisher
    {
        public NumCountChange NumChangeDelegate; //声明委托类型变量

        public event NumCountChange NumChange; //声明事件

        public int count { set; get; } = 99;

        //当调用该函数时,由发布者来触发对应的事件
        public void InvokeEvent()
        {
            if (NumChange != null) //当委托中有函数注册时(即为非空),就会触发该事件
            {
                ++count;
                NumChange(count);//触发该事件
            }
        }

    }

    /// <summary>
    /// 事件订阅者类
    /// </summary>
    class Subscriber
    {
        //该函数会注册到委托事件中,一旦事件发布者触发该事件时,订阅者就会接收到该事件进行执行
        public void OnNumChange(int count)
        {
            Console.WriteLine("Subscriber the changed number is {0}", count);
        }
    }
}

7、事件中的观察者模式

1、事件触发模式
事件的触发和反应是一种观察者模式,主要由两部分组成:
被监视者:相当于事件发布者,其中有一些属性来被其它对象所监视。
观察者:相当于事件的订阅者,它会观察被监视对象的某些属性,当这些属性发生变化时,会触发观察者做出对应的反应。观察者一般可以有多个。
被监视对象只管触发事件,而不管是否有人订阅了该事件。
观察者只根据自身的需要,来决定是否需要注册订阅该事件,以对该事件产生响应,而不管是谁触发了该事件

具体实例
加热水的加热器,时刻显示水温的显示器,当水温达到90度时的报警器。这三者来共同组成该程序,代码如下:

namespace 事件详解2
{
    class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();
            Display display = new Display();

            heater.curTemperature += alarm.MakeAlarm; //将报警函数注册到事件上
            heater.curTemperature += display.ShowTemperature; //将显示温度函数注册到事件上

            heater.Heating();//开始加热

        }
    }

    public delegate void SendTemperatureEvent(int num);

    /// <summary>
    /// 加热器:负责加热。相当于事件发布者,用来发布当前水温。
    /// </summary>
    class Heater
    {
        public event SendTemperatureEvent curTemperature;

        private int temperature;  //水温
        private int maxTemp = 100;

        public void Heating()
        {
            //水温从85度开始
            for (int i = 85; i <= maxTemp; ++i)
            {
                temperature = i;

                if (curTemperature != null)
                {
                    curTemperature(temperature);  //触发事件
                }

                Thread.Sleep(1000);  //线程睡眠1秒
            }

            Console.WriteLine("现在水温 100℃ !!!");
            Console.ReadKey();
        }


    }

    /// <summary>
    /// 报警器:当水温达到一定的值时,进行报警
    /// </summary>
    class Alarm
    {
        //订阅者:从加热器那里订阅水温,当水温达到一定值,就开始报警。
        public void MakeAlarm(int temperature)
        {
            if (temperature > 90)
            {
                Console.WriteLine($"现在水温 {temperature}");
            }
        }
    }

    /// <summary>
    /// 显示器:显示水温值
    /// </summary>
    class Display
    {
        //订阅者:从加热器那里订阅水温,并进行显示。
        public void ShowTemperature(int temperature)
        {
            Console.WriteLine($"水温 :{temperature}");
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值