事件与委托
一、委托 (Delegates)
-
定义:委托是一种类型安全的方法引用,它可以指向一个或多个方法,并可以通过该委托调用这些方法。即委托该方法用以调用其他方法。
-
声明:
public delegate void MyDelegate(string message);
-
使用:
- 创建委托实例并指向方法:
void MyMethod(string msg)
{
Console.WriteLine(msg);
}
MyDelegate del = new MyDelegate(MyMethod);
del("Hello, Delegates!"); // 输出:Hello, Delegates!- 委托可以指向多个方法(多播委托):
del += AnotherMethod; // 追加方法
del -= AnotherMethod; // 去除方法
del += AnotherMethod; // 追加方法
del("Hello again!"); // 将调用 MyMethod 和 AnotherMethod
del = null //清空委托- 委托可以传参,只能绑定对应参数的方法,调用时传参:
public delegate void MyDelegate(int number, string message);
public void MyMethod(int number, string message)
{
Console.WriteLine($"Number: {number}, Message: {message}");
}
MyDelegate del = new MyDelegate(MyMethod);
del(42, "Hello, Delegates!"); // 输出:Number: 42, Message: Hello, Delegates!
- 可以使用匿名方法和Lambda表达式
//匿名方法
MyDelegate del = delegate(int number, string message)
{
Console.WriteLine($"Anonymous - Number: {number}, Message: {message}");
};
del(100, "Hello from Anonymous Method!");
// 输出:Anonymous - Number: 100, Message: Hello from Anonymous Method!
//Lambda表达式
MyDelegate del = (number, message) =>
{
Console.WriteLine($"Lambda - Number: {number}, Message: {message}");
};
del(200, "Hello from Lambda!");
// 输 出:Lambda - Number: 200, Message: Hello from Lambda!
实际使用中,往往会直接使用事件而不是委托:
二、事件 (Events)
- 定义:事件是委托的封装,允许类或对象向其他类或对象提供通知。通常用于实现发布-订阅模式。
- 声明:
public class MyEventPublisher
{
public event MyDelegate MyEvent; // 声明事件
} - 触发事件:
protected virtual void OnMyEvent(string message)
{
MyEvent?.Invoke(message); // 触发事件
} - 订阅事件:
- 在另一个类中订 阅事件:
public class MyEventSubscriber
{
public void Subscribe(MyEventPublisher publisher)
{
publisher.MyEvent += HandleEvent; // 订阅事件
publisher.MyEvent -= HandleEvent; // 取消事件
}
private void HandleEvent(string message)
{
Console.WriteLine($"Event received: {message}");
}
}
为什么常用事件而不是委托(来源于网络)
- 解耦合性:
- 事件提供了一种更好的解耦合机制。发布者不需要知道订阅者的具体实现,允许多个订阅者同时响应同一事件,而不会影响彼此的实现。
- 灵活性和多播能力:
- 事件支持多播,可以有多个订阅者,而委托通常是单一的。当需要通知多个对象时,事件显得更为合适。
- 安全性:
- 事件的封装性使得外部无法直接调用事件,而只能通过订阅和触发的方式使用,这有助于避免不必要的调用和潜在的错误。
- 标准化和一致性:
- 使用事件是C#语言本身提供的特性,符合事件驱动编程的标准,容易被其他开发者理解和使用。Unity和许多框架也倾向于使用事件,从而保持API的一致性。
- 便于调试:
- 事件的订阅和触发方式更容易在调试时进行跟踪和监控,尤其是在复杂的应用程序中,可以快速识别事件的发送和接收情况。
为什么?(个人理解)
我认为事件的优点在于封装,在事件中,事件是个容器,包含其拥有的方法,给出统一的操作唤醒,不允许太过自主的调用,减少了对具体实现的依赖。 以此带来了解耦合,灵活多播,使用安全等优点。