C# 委托与事件

委托与事件可以用异世界冒险来类比

csharp 复制代码
using System;

namespace LHJ {

    
    class Publisher {//编写事件,发布委托

        public delegate int PublisherDelegate(int i);//委托
        public event PublisherDelegate WhenClick;//委托针对的事件

        public int happened() {//这件事发生了
            int something = WhenClick(2);
            return something;
        }

    }

    class Subscriber {
        public int getNum(int a) {//冒险者
            return a;
        } 
    }

    class TODO {
        public static void Main(string[] args) {
            Publisher pp = new Publisher();//先得有冒险者工会(发布者)
            Subscriber ss = new Subscriber();//和冒险队(订阅者)

            pp.WhenClick += new Publisher.PublisherDelegate(ss.getNum);
            //选择冒险者接受委托,加入此次事件(一个事件可以有多个委托

            Console.WriteLine(pp.happened());//这件事发生了(大家去搞事了

        }
    }

}

上文简单的实现了一次事件的发生,然后调动了因为此事发生而做出的反应(委托)

委托

C# 中的委托(Delegate类似于 C 或 C++ 中的函数指针 ,是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。委托特别适用于实现事件和回调方法,所有的委托都派生自 System.Delegate 类。在实例化委托时,可以将委托的实例与具有相同返回值类型的方法相关联,这样就可以通过委托来调用方法。另外,使用委托还可以将方法作为参数传递给其他方法。

委托对象有一个非常有用的属性,那就是可以通过使用+运算符将多个对象分配给一个委托实例 ,同时还可以使用-运算符从委托中移除已分配的对象 ,当委托被调用时会依次调用列表中的委托。委托的这个属性被称为委托的多播,也可称为组播,利用委托的这个属性,您可以创建一个调用委托时要调用的方法列表。(依次按加入顺序调用

事件

C# 中,事件(Event)可以看作是用户的一系列操作,例如点击键盘的某个按键、单击/移动鼠标等,当事件发生时我们可以针对事件做出一系列的响应,例如退出程序、记录日志等等。C# 中线程之间的通信就是使用事件机制实现的。

事件需要在类中声明和触发,并通过委托与事件处理程序关联。

事件可以分为发布器和订阅器两个部分,其中

发布器 是一个包含事件和委托的对象,事件和委托之间的联系也定义在这个类中,发布器类的对象可以触发事件,并使用委托通知其他的对象;(发布事件,这个事件会有委托,但是委托给什么冒险者对于我这个任务 事件来说是不知道的

订阅器 则是一个接收事件并提供事件处理程序的对象,发布器类中的委托调用订阅器类中的方法(事件处理程序)。(提供各种各样的冒险者来接受委托,响应事件

若要在类中声明一个事件,首先需要为该事件声明一个委托类型,例如:

csharp 复制代码
public delegate void delegate_name(string status);

然后使用 event 关键字来声明事件本身,如下所示:

csharp 复制代码
// 基于上面的委托定义事件
public event delegate_name event_name;

上例中定义了一个名为 delegate_name 和名为 event_name 的事件,当事件触发的时侯会调用委托。

有关事件我们需要注意以下几点

发布器确定何时触发事件,订阅器确定对事件作出何种响应;

一个事件可以拥有多个订阅器,同时订阅器也可以处理来自多个发布器的事件;

没有订阅器的事件永远也不会触发;
事件通常用于定义针对用户的操作,例如单击某个按钮;

如果事件拥有多个订阅器,当事件被触发时会同步调用所有的事件处理程序;

.NET 类库中,事件基于 EventHandler 委托和 EventArgs 基类。

此外

解耦和事件驱动编程:这有助于实现代码之间的松耦合,因为发送事件的对象(事件源)不需要知道哪些对象(事件接收器)将处理这些事件。事件源只需要触发事件,而委托将确保所有注册的方法(事件处理程序)得到调用。

方法作为参数传递:委托可以作为方法的参数传递,这使得方法能够接收和执行其他方法作为参数。这增加了代码的灵活性和可重用性,因为你可以根据需要在运行时动态地指定要执行的方法。

最后

C#中,事件是特殊的成员,它允许其他类或对象订阅或取消订阅。

这是一个老师来的代码

csharp 复制代码
using System;
using System.Xml.Serialization;
using static CLASS_MISSION.Teacher;

namespace CLASS_MISSION {
    class Teacher {
        public delegate void TeacherDelegate(string name);
        public event TeacherDelegate TeacherCome;

        public void ComeHappen() {
            TeacherCome("Tom");
        }
    }

    class Student {
        public void SayHi(string name) {
            System.Console.WriteLine("{0}好!", name);
        }
    }

    class TODO {
        public static void Main(string[] args) {
            Teacher tt = new Teacher();
            Student ss = new Student();

            TeacherDelegate td = new Teacher.TeacherDelegate(ss.SayHi);

            tt.TeacherCome += td;

            tt.ComeHappen();
        }
    }
}
相关推荐
2401_8581205343 分钟前
Spring Boot框架下的大学生就业招聘平台
java·开发语言
转调1 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
Java探秘者1 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
2303_812044461 小时前
Bean,看到P188没看了与maven
java·开发语言
秋夫人1 小时前
idea 同一个项目不同模块如何设置不同的jdk版本
java·开发语言·intellij-idea
不穿格子衬衫2 小时前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序
萧鼎2 小时前
Python调试技巧:高效定位与修复问题
服务器·开发语言·python
wdxylb2 小时前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法
Geek之路2 小时前
QT系统学习篇(1)
开发语言·qt·学习
罗曼蒂克在消亡2 小时前
GraphQL规范
开发语言·graphql