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();
        }
    }
}
相关推荐
学编程的小白狼12 分钟前
C#:多线程
开发语言·c#
island131413 分钟前
JAVA Web 期末速成
java·开发语言·前端
珊瑚里的鱼18 分钟前
【滑动窗口】LeetCode 1004题解 | 最大连续1的个数 Ⅲ
开发语言·c++·笔记·算法·leetcode
使者大牙19 分钟前
【C语言基础语法入门】通过简单实例快速掌握C语言核心概念
c语言·开发语言
2401_8956108243 分钟前
Java 后端基础 Maven
java·开发语言·maven
LAM LAB1 小时前
【VBA/word】批量替换字体大小
开发语言·c#·word
zzc9211 小时前
怎么用Origin画出MATLAB效果的3D时频图
开发语言·matlab
小峰编程1 小时前
Python函数——万字详解
linux·运维·服务器·开发语言·前端·网络·python
芯眼1 小时前
正点原子STM32新建工程
开发语言·c++·stm32·单片机·软件工程
海盐泡泡龟1 小时前
Javascript本地存储的方式有哪些?区别及应用场景?(含Deep Seek讲解)
开发语言·javascript·ecmascript