委托
C# 中的委托(Delegate)是一种类型安全的函数指针,它允许你将方法作为参数传递给其他方法。委托可以引用一个或多个方法,并且可以在运行时调用这些方法。它们是实现事件和回调的基础。
委托的基本概念
- 定义委托:首先需要定义一个委托类型,这指定了可被委托调用的方法签名。
- 实例化委托:创建一个委托实例,该实例指向具体的一个或多个方法。
- 使用委托:通过委托实例来调用其关联的方法。
定义委托
要定义一个委托,你需要使用 delegate 关键字。例如:
public delegate void MyDelegate(string message);
这里定义了一个名为 MyDelegate 的委托,它可以用来引用任何带有单个 string 参数并且没有返回值的方法。
实例化委托和使用委托
一旦定义了委托类型,你可以创建该类型的实例并让它指向某个方法。例如:
public class Program { public static void ShowMessage(string message) { Console.WriteLine(message); } public static void Main() { // 创建委托实例并指向ShowMessage方法 MyDelegate myDelegate = new MyDelegate(ShowMessage); // 通过委托调用方法 myDelegate("Hello, World!"); } }
在这个例子中,myDelegate
是一个委托实例,它被初始化为指向 ShowMessage
方法。之后可以通过 myDelegate
来间接调用 ShowMessage
方法。
多播委托
C# 中的委托还支持多播(即一个委托对象可以包含对多个方法的引用)。当你调用一个多播委托时,所有绑定到该委托的方法都会按顺序执行。
public static void AnotherMethod(string message) { Console.WriteLine($"Another: {message}"); } public static void Main() { MyDelegate first = new MyDelegate(ShowMessage); MyDelegate second = new MyDelegate(AnotherMethod); // 合并两个委托 MyDelegate combined = first + second; // 调用combined会依次执行ShowMessage和AnotherMethod combined("Hello, Multicast!"); }
事件
事件是一个使用event关键字声明的成员,它基于委托类型。
你可以自定义一个委托类型并使用它来定义事件。
事件的基本概念
-
事件的拥有者:这是声明事件的对象或类。例如,在一个计时器类中,计时器本身是事件的拥有者。
-
事件本身:这是一个使用
event
关键字声明的成员,它基于委托类型。当特定条件满足时,事件会被触发(即调用所有注册到该事件的处理方法)。 -
事件处理器:这是响应事件的方法。它们是与事件关联的函数,当事件被触发时,这些方法将被执行。
-
事件订阅:这是将事件处理器添加到事件的过程。通过
+=
操作符来完成订阅,而-=
操作符用来取消订阅。 -
事件触发:这是执行所有已注册的事件处理器的行为。通常是通过调用委托实例来实现的。
事件的工作原理
-
当一个事件被定义后,它可以像字段一样被初始化,但它是不可直接访问的(只能通过
+=
和-=
进行订阅/退订)。这是因为event
关键字提供了额外的封装,确保了外部代码不能直接修改事件的内部状态。 -
事件本质上是一个委托类型的字段,这意味着它可以指向一个或多个方法。当事件被触发时,所有注册到该事件的方法都会按顺序执行。
-
事件通常会携带一些数据给事件处理器。这通过创建自定义的
EventArgs
派生类来实现,然后将其作为参数传递给事件处理器。
自定义委托和事件
这里是一个例子,展示如何创建自定义委托和事件:
首先,定义一个自定义委托:
// 定义一个自定义委托 public delegate void CustomEventHandler(string message);
然后,可以在类中使用这个自定义委托来定义一个事件:
public class EventPublisher { // 使用自定义委托定义一个事件 public event CustomEventHandler CustomEvent; // 保护方法用于触发事件 protected virtual void OnCustomEvent(string message) { CustomEvent?.Invoke(message); } // 产生事件的动作 public void DoSomething() { Console.WriteLine("Doing something..."); // 在某些条件下触发事件 OnCustomEvent("Something happened!"); } }
最后,在客户端代码中订阅和处理这个事件:
class Program { static void Main() { var publisher = new EventPublisher(); // 订阅事件 publisher.CustomEvent += (message) => Console.WriteLine($"Custom Event received: {message}"); // 执行操作,可能会触发事件 publisher.DoSomething(); } }
在这个例子中,CustomEventHandler 是一个自定义的委托类型,而 CustomEvent 是一个基于这个委托类型的事件。客户端代码可以像使用 EventHandler<TEventArgs> 那样使用 += 来订阅这个事件。
EventHandler
在 C# 中,EventHandler
是一种特殊的委托类型,专门用于事件处理。它定义在 System
命名空间中,并且通常用来实现发布-订阅模式,这是 .NET 框架中处理事件的标准方式。
EventHandler
的定义如下:
public delegate void EventHandler(object sender, EventArgs e);
这里有几个关键点需要注意:
-
sender 参数:这是一个
object
类型的参数,代表触发事件的对象。这通常是发出事件的那个对象实例(比如一个按钮控件)。 -
EventArgs 参数:这是一个
EventArgs
类型的参数,提供了与事件相关的数据。对于不需要传递额外信息的基本事件,可以使用这个基类。如果需要携带更多信息,则可以继承自EventArgs
创建特定的事件参数类。
使用示例
下面是一个简单的例子,展示如何使用 EventHandler
来定义和处理事件:
using System; // 定义一个自定义的EventArgs类来携带额外的数据 public class MyEventArgs : EventArgs { public string Message { get; set; } public MyEventArgs(string message) { Message = message; } } // 一个类,包含一个事件 public class EventPublisher { // 定义事件 public event EventHandler<MyEventArgs> MyEvent; // 触发事件的方法 protected virtual void OnMyEvent(MyEventArgs e) { MyEvent?.Invoke(this, e); } // 产生事件的动作 public void DoSomething() { Console.WriteLine("Doing something..."); // 在某些条件下触发事件 OnMyEvent(new MyEventArgs("Something happened!")); } } class Program { static void Main() { var publisher = new EventPublisher(); // 订阅事件 publisher.MyEvent += (sender, e) => Console.WriteLine($"Event received: {e.Message}"); // 执行操作,可能会触发事件 publisher.DoSomething(); } }
在这个例子中:
- 我们定义了一个
MyEventArgs
类来携带事件数据。 EventPublisher
类有一个MyEvent
事件,当调用DoSomething
方法时,该事件会被触发。- 在主程序中,我们创建了
EventPublisher
的一个实例,并为MyEvent
事件添加了一个处理器(lambda 表达式),该处理器将在事件被触发时打印一条消息。
通过这种方式,EventHandler
和它的泛型版本 EventHandler<TEventArgs>
提供了一种标准化的方式来处理事件,使得组件之间的通信更加松散耦合。
标签:EventHandler,委托,C#,void,事件,message,public From: https://www.cnblogs.com/ban-boi-making-dinner/p/18500458