委托与事件可以用异世界冒险来类比
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();
}
}
}