C#事件(个人理解)

以下的内容纯属个人理解,由于本人也是个小白,所以如果理解有错误的话,希望多多指正
废话不多说,正式开始
在上一篇博客中说的是委托,所谓的委托就是使用函数方法的一种渠道,通过过这种渠道,我们可以通过一个委托的调用时,执行一个到多个函数方法,当然了这些函数方法也不是随意调用的,必须要与委托声明时一样的形式,详情请见上一篇博客,这篇博客主要来说一说什么是事件。

在现实中,有数不清的可以称之为事件的情况,比如你拿起了水杯,给手机充电,做一个项目时,小组负责人给你下达了任务,上市公司的总公司给其旗下的子公司下达任务等等,我们今天就用举例中的最后一个例子来说明一下,到底什么是事件?

首先要说的就是一个个人认为很重要的概念,事件其实就是委托,但是在某些地方又不能这样说,但是能确定的就是,事件其实是委托的一种特殊使用方式。
来看一下事件的简单使用(看不懂没关系)

using System;

delegate void Handler();//声明委托可用来定义单个委托多广播或者是事件
class Event_Text
{
    public event Handler Event_text;//声明使用Handler委托的事件

    public void circular()
    {
        for (int i = 0; i < 20; i++)
        {
            if (i % 2 == 0)
            {
                Event_text();//调用的是注册的事件,注意:事件的+=、-=操作符可以在类的外部使用,调用事件只能在声明事件的类的内部使用。
            }
        }
    }
}

class Text
{
    public Text(Event_Text event_Text)//定义一个 Event_Text类型的变量
    {
        //指向的是这个类里面所注册的事件
        event_Text.Event_text += Text_Event;//把这个分公司的接收系统添加到住公司发布的子名单里面
    }

    void Text_Event()
    {
        Console.WriteLine("Text" + 1);
    }
}

class Text2
{
    public Text2(Event_Text event_Text)
    {
        event_Text.Event_text += Text_Event;
    }

    void Text_Event()
    {
        Console.WriteLine("Text" + 2);
    }
}

class Program
{
    static void Start()
    {
        Event_Text event_ = new Event_Text();
      
        Text text = new Text(event_);
    
        Text2 text2 = new Text2(event_);


        event_.circular();
    }
}

我们来理一下这个例子的结构。
1.在本例子中声明了一个委托,在声明委托 的时候参数表明,这个这个委托的使用情况是返回值为void,并且没有参数的函数方法(在上一篇博客中有原因)。
2.声明使用对应委托的事件
3.调用注册的事件(注意:事件之间的添加或者移除也就是-=和+=可以在类的外部使用,但是调用事件只能在声明事件的类的内部使用)。
4.在不同的类中通过构造函数,将声明事件的那个类的对象传入,并且为这个对象对应的事件添加了本类中的私有成员函数
5.将实例化的类的对象传到各个对象中

通过这样梳理可能还是很不明白,那就往下看

例子中的第一个类Event_Text相当于一个总公司,如果这个总公司不存在的话,事件也不可能被调用,存在了这个总公司之后,再总公司中存在这样一件事,什么事呢?circular()这件事,当总公司想要执行这件事的时候,他自己是没有解决这件事的方法的他不会,但是他有旗下的公司,也就是类Text和类Text2,这两个类里面有解决这件事的办法,所以如果总共公司想要处理这件事,就必须来通知旗下的子公司来提供解决的方法,虽然通知了子公司来解决,但是子公司的方法太多,它也不知道具体要使用什么方法来解决这件事,怎么办呢?再子公司成立的时候,就把这件事的解决方法与总公司的确定任务关联起来,也就是将函数方法注册到事件里面,也就是例子中的

。。。
public Text(Event_Text event_Text)
    {
        
        event_Text.Event_text += Text_Event;
    }
。。。
public Text2(Event_Text event_Text)
    {
        event_Text.Event_text += Text_Event;
    }
    。。。

所以事件和委托的区别也就出来了,事件其实就是委托的一种特殊的使用方法,只不过他比委托要更安全一点,事件只能再声明事件的那个类中使用,而且不能直接调用,是要通过一个事件的导火索来使用(第一个类的circular()函数方法)
下面是添有注释的代码,可能更容易理解

using System;

delegate double max(int a, int b);//声明委托
class Event_Text
{
    public event Handler Event_text;//声明使用Handler委托的事件

    public void circular()
    {
        for (int i = 0; i < 20; i++)
        {
            if (i % 2 == 0)
            {
                Event_text();//调用的是注册的事件,注意:事件的+=、-=操作符可以在类的外部使用,调用事件只能在声明事件的类的内部使用。
            }
        }
    }
}

class Text
{
    public Text(Event_Text event_Text)//定义一个 Event_Text类型的变量
    {
        //指向的是这个类里面所注册的事件
        event_Text.Event_text += Text_Event;//把这个分公司的接收系统添加到住公司发布的子名单里面
    }

    void Text_Event()
    {
        Console.WriteLine("Text" + 1);
    }
}

class Text2
{
    public Text2(Event_Text event_Text)
    {
        event_Text.Event_text += Text_Event;
    }

    void Text_Event()
    {
        Console.WriteLine("Text" + 2);
    }
}

class Program
{
    static void Start()
    {

        //在从总公司往下面的子公司发布任务的时候,首先要存在这个公司
        Event_Text event_ = new Event_Text();
        //将任务事件下发,而对这个任务所需要做出的反应在子公司注册的时候iiu已经定义好就等总公司下达任务
        Text text = new Text(event_);
        //将任务事件下发,而对这个任务所需要做出的反应在子公司注册的时候iiu已经定义好就等总公司下达任务
        Text2 text2 = new Text2(event_);

        //如果没有下一条语句的话,总公司的任务永远都是在筹备或者商讨中还未完全成型
        event_.circular();//只有执行这句话的时候,才会出动事件委托,也就是任务成型正式下达

        max zuida = new max(Cin);
    }

    
}

想过吗?事件可以实现的功能其实委托也都能实现,那为什么还要有事件这一用法呢?,在委托中,不管是那个类都有权限向委托中添加函数方法,也即是都有权限对委托进行修改,这是我们所不想看到的,开捋一下,客户端可以修改服务器委托所绑定的函数方法,在某些情况下,这样是很可怕的,所以事件应运而生,上面已经说过,事件只能在声明事件的类中访问。并且,在多线程的应用中,也可以看到,委托其实是在主线程中调用,而事件则是另开线程进行。

所以事件其实是将委托进行封装,只能通过事件进行委托事件的添加和删除,保障了委托的封装性。
只有在特定的时候由发布者进行事件的触发,限制了客户端的权限,保护代码。

发布了67 篇原创文章 · 获赞 3 · 访问量 1906

猜你喜欢

转载自blog.csdn.net/lfanyize/article/details/103148227