C# 自定义事件与委托
1. 什么是委托(Delegate)
委托就像是一个"方法容器",它可以存储一个或多个方法。当调用委托时,所有存储在其中的方法都会被执行。
简单委托示例
// 1. 定义一个委托类型
public delegate void SimpleDelegate(string message);
class Program
{
// 2. 创建一个符合委托签名的方法
static void ShowMessage(string msg)
{
Console.WriteLine("显示消息: " + msg);
}
static void Main()
{
// 3. 创建委托实例并关联方法
SimpleDelegate myDelegate = ShowMessage;
// 4. 调用委托
myDelegate("你好,世界!");
}
}
2. 什么是事件(Event)
事件是基于委托的,它是一种特殊的委托,主要用于实现"发布-订阅"模式。比如按钮点击事件 - 按钮发布点击事件,其他代码可以订阅这个事件。
简单事件示例
// 1. 定义一个委托类型(事件处理器的签名)
public delegate void ButtonClickHandler(object sender, EventArgs e);
// 2. 创建一个包含事件的类
class Button
{
// 3. 声明事件
public event ButtonClickHandler Click;
// 4. 触发事件的方法
public void OnClick()
{
if (Click != null) // 检查是否有订阅者
{
Click(this, EventArgs.Empty); // 触发事件
}
}
}
class Program
{
// 5. 事件处理方法
static void Button_Click(object sender, EventArgs e)
{
Console.WriteLine("按钮被点击了!");
}
static void Main()
{
Button btn = new Button();
// 6. 订阅事件
btn.Click += Button_Click;
// 7. 模拟按钮点击
btn.OnClick();
}
}
3. 自定义事件完整示例
让我们创建一个温度监控器的例子,当温度超过阈值时触发事件:
// 1. 自定义事件参数类
public class TemperatureChangedEventArgs : EventArgs
{
public double OldTemperature { get; }
public double NewTemperature { get; }
public DateTime ChangeTime { get; }
public TemperatureChangedEventArgs(double oldTemp, double newTemp)
{
OldTemperature = oldTemp;
NewTemperature = newTemp;
ChangeTime = DateTime.Now;
}
}
// 2. 定义委托
public delegate void TemperatureChangedHandler(object sender, TemperatureChangedEventArgs e);
// 3. 温度监控器类
class TemperatureMonitor
{
private double _currentTemperature;
// 4. 声明事件
public event TemperatureChangedHandler TemperatureChanged;
public double CurrentTemperature
{
get { return _currentTemperature; }
set
{
if (_currentTemperature != value)
{
double oldTemp = _currentTemperature;
_currentTemperature = value;
// 5. 触发事件
OnTemperatureChanged(oldTemp, _currentTemperature);
}
}
}
// 6. 触发事件的方法
protected virtual void OnTemperatureChanged(double oldTemp, double newTemp)
{
TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs(oldTemp, newTemp));
}
}
class Program
{
static void Main()
{
TemperatureMonitor monitor = new TemperatureMonitor();
// 7. 订阅事件
monitor.TemperatureChanged += Monitor_TemperatureChanged;
// 8. 改变温度(会触发事件)
monitor.CurrentTemperature = 25.0;
monitor.CurrentTemperature = 30.5;
monitor.CurrentTemperature = 28.0;
}
// 9. 事件处理方法
private static void Monitor_TemperatureChanged(object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine($"温度变化: {e.OldTemperature}°C → {e.NewTemperature}°C");
Console.WriteLine($"变化时间: {e.ChangeTime}");
Console.WriteLine("----------------------");
}
}
4. 使用内置的 EventHandler 委托
.NET 提供了 EventHandler<TEventArgs>
泛型委托,可以简化代码:
class TemperatureMonitor
{
// 使用内置的 EventHandler 委托
public event EventHandler<TemperatureChangedEventArgs> TemperatureChanged;
// 其余代码与之前相同...
}
5. 总结
委托:方法的容器,可以存储和调用一个或多个方法
事件:基于委托的机制,用于实现发布-订阅模式
自定义事件步骤:
定义事件参数类(继承自 EventArgs)
定义委托(或使用内置的 EventHandler)
在类中声明事件
编写触发事件的方法
订阅事件并处理
记住:事件让我们的代码可以"通知"其他部分发生了某些事情,而不需要知道谁会处理这些事件!