c#事件案例与分析
using System;
using System.Collections.Generic;
namespace EventExample
{
// 定义事件数据
public class DataReceivedEventArgs : EventArgs
{
public string Data { get; }
public DataReceivedEventArgs(string data)
{
Data = data;
}
}
// 发布者类
public class Publisher
{
// 定义事件
public event EventHandler<DataReceivedEventArgs> DataReceived;
// 模拟数据接收
public void ReceiveData(string data)
{
Console.WriteLine("Publisher: Receiving data...");
OnDataReceived(data);
}
// 触发事件
protected virtual void OnDataReceived(string data)
{
try
{
DataReceived?.Invoke(this, new DataReceivedEventArgs(data));
}
catch (Exception ex)
{
Console.WriteLine($"Error while notifying subscribers: {ex.Message}");
}
}
}
// 订阅者类
public class Subscriber
{
private readonly string _name;
public Subscriber(string name)
{
_name = name;
}
// 处理事件的方法
public void OnDataReceived(object sender, DataReceivedEventArgs e)
{
if (e == null || string.IsNullOrEmpty(e.Data))
{
Console.WriteLine($"{_name} received empty data.");
return;
}
Console.WriteLine($"{_name} received data: {e.Data}");
}
}
class Program
{
static void Main(string[] args)
{
// 创建发布者
Publisher publisher = new Publisher();
// 创建订阅者
Subscriber subscriber1 = new Subscriber("Subscriber 1");
Subscriber subscriber2 = new Subscriber("Subscriber 2");
// 订阅事件
publisher.DataReceived += subscriber1.OnDataReceived;
publisher.DataReceived += subscriber2.OnDataReceived;
// 模拟接收数据
publisher.ReceiveData("Hello, World!");
// 取消订阅
publisher.DataReceived -= subscriber1.OnDataReceived;
// 再次模拟接收数据
publisher.ReceiveData("Goodbye, World!");
Console.ReadLine();
}
}
}
1. 事件定义
首先,在 Publisher 类中定义了一个事件 DataReceived,它的类型是 EventHandler<DataReceivedEventArgs>。这意味着该事件可以传递一个 DataReceivedEventArgs 类型的参数,通常用于包含与事件相关的数据。
public event EventHandler<DataReceivedEventArgs> DataReceived;
2. 事件处理方法
在 Subscriber 类中定义了一个方法 OnDataReceived,这个方法将会作为事件处理程序(event handler)来处理 DataReceived 事件。当事件被触发时,OnDataReceived 方法会被调用,并接收事件的发出者(sender)和事件数据(DataReceivedEventArgs)作为参数。
public void OnDataReceived(object sender, DataReceivedEventArgs e)
{
// 处理事件
}
3. 订阅事件
publisher.DataReceived += subscriber1.OnDataReceived; 这行代码的作用是将 subscriber1 的 OnDataReceived 方法注册为 publisher 的 DataReceived 事件的处理程序。具体的执行逻辑如下:
事件订阅:使用 += 运算符将 subscriber1.OnDataReceived 方法添加到 DataReceived 事件的事件处理列表中。这意味着,当 DataReceived 事件被触发时,所有订阅了该事件的方法(包括 subscriber1.OnDataReceived)都会被调用。
4. 事件触发
在 Publisher 类中,有一个方法 OnDataReceived,它会触发 DataReceived 事件。这个方法会检查是否有订阅者,并调用它们的事件处理方法:
protected virtual void OnDataReceived(string data)
{
DataReceived?.Invoke(this, new DataReceivedEventArgs(data));
}
5. 事件处理
当调用 publisher.ReceiveData("Hello, World!"); 时,会触发 DataReceived 事件,导致 OnDataReceived 方法被调用。所有订阅了 DataReceived 事件的方法都会被执行。在这种情况下,subscriber1.OnDataReceived 将会被调用,并传入 publisher 作为 sender 和包含数据 "Hello, World!" 的 DataReceivedEventArgs 对象。
总结
publisher.DataReceived += subscriber1.OnDataReceived; 是将 subscriber1 的 OnDataReceived 方法注册为事件处理程序的过程。
当 DataReceived 事件被触发时,所有注册的处理程序(包括 subscriber1.OnDataReceived)会被依次调用,处理相关的事件数据。
这种机制使得发布者(Publisher)和订阅者(Subscriber)之间实现了松耦合的关系,发布者不需要知道具体的订阅者,只需触发事件即可。