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();
        }
    }
}
相关推荐
倔强的石头1067 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
Watermelo61711 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
军训猫猫头1 小时前
20.抽卡只有金,带保底(WPF) C#
ui·c#·wpf
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J2 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB2 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
计算机学长大白3 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
PieroPc4 小时前
Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印
开发语言·python·excel
2401_857439697 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php