跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C Sharp 事件订阅
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C#事件订阅 = == 简介 == '''事件订阅'''是C#中实现'''发布-订阅模式'''的核心机制,允许对象(发布者)通知其他对象(订阅者)状态变化或特定动作的发生。事件基于委托构建,是.NET框架中实现松耦合通信的关键特性,广泛应用于用户界面交互、异步编程和组件化设计。 == 核心概念 == === 事件模型的三要素 === 1. '''事件发布者(Publisher)''':包含事件定义并触发事件的对象。 2. '''事件订阅者(Subscriber)''':通过事件处理器(Event Handler)响应事件的对象。 3. '''事件处理器(Delegate)''':定义事件签名的方法契约。 <mermaid> classDiagram class Publisher{ +event EventHandler MyEvent +RaiseEvent() } class Subscriber{ +HandleEvent() } Publisher --> EventHandler Subscriber ..|> EventHandler </mermaid> == 语法详解 == === 1. 定义事件 === 使用`event`关键字声明事件,需指定委托类型(通常用`EventHandler`或其泛型版本): <syntaxhighlight lang="csharp"> public class Button { // 声明事件 public event EventHandler? Clicked; } </syntaxhighlight> === 2. 订阅事件 === 通过`+=`操作符添加事件处理器: <syntaxhighlight lang="csharp"> Button button = new Button(); button.Clicked += OnButtonClicked; // 订阅 void OnButtonClicked(object? sender, EventArgs e) { Console.WriteLine("按钮被点击!"); } </syntaxhighlight> === 3. 触发事件 === 在发布者内部调用事件(需进行null检查): <syntaxhighlight lang="csharp"> public void RaiseEvent() { Clicked?.Invoke(this, EventArgs.Empty); } </syntaxhighlight> == 完整示例 == <syntaxhighlight lang="csharp"> // 温度监控系统示例 public class TemperatureSensor { public event EventHandler<TemperatureChangedEventArgs>? TemperatureChanged; public void SimulateTemperatureChange() { Random rnd = new Random(); double newTemp = rnd.NextDouble() * 100; TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs(newTemp)); } } public class TemperatureChangedEventArgs : EventArgs { public double Temperature { get; } public TemperatureChangedEventArgs(double temperature) => Temperature = temperature; } // 订阅者 public class Display { public void Subscribe(TemperatureSensor sensor) { sensor.TemperatureChanged += ShowTemperature; } private void ShowTemperature(object? sender, TemperatureChangedEventArgs e) { Console.WriteLine($"当前温度: {e.Temperature:F1}°C"); } } // 使用 var sensor = new TemperatureSensor(); var display = new Display(); display.Subscribe(sensor); sensor.SimulateTemperatureChange(); // 输出示例:当前温度: 76.3°C </syntaxhighlight> == 高级主题 == === 多播委托 === 事件支持多个订阅者,按添加顺序依次调用: <syntaxhighlight lang="csharp"> button.Clicked += Handler1; button.Clicked += Handler2; // 触发时 Handler1 → Handler2 顺序执行 </syntaxhighlight> === 取消订阅 === 使用`-=`操作符移除订阅: <syntaxhighlight lang="csharp"> button.Clicked -= OnButtonClicked; </syntaxhighlight> === 匿名方法与Lambda表达式 === <syntaxhighlight lang="csharp"> button.Clicked += (sender, e) => Console.WriteLine("匿名处理器"); </syntaxhighlight> == 线程安全模式 == 推荐使用以下模式确保线程安全的事件触发: <syntaxhighlight lang="csharp"> EventHandler? handler = TemperatureChanged; handler?.Invoke(this, e); </syntaxhighlight> == 设计准则 == 1. 事件命名使用动词短语(如`ValueChanged`) 2. 遵循`EventHandler<TEventArgs>`标准模式 3. 事件参数应继承自`EventArgs` 4. 在类销毁前取消所有订阅(避免内存泄漏) == 常见问题 == === Q:事件与委托的区别? === A:事件是委托的封装,仅允许: * 发布者:触发事件 * 订阅者:添加/移除处理器 === Q:为什么事件触发前要检查null? === A:未订阅的事件为null,直接调用会导致<code>NullReferenceException</code>。 == 数学表示 == 事件订阅可形式化为: <math> \begin{cases} Publisher \triangleright Event &= \sum_{i=1}^{n} Handler_i \\ Handler &\in Delegate \end{cases} </math> == 实际应用场景 == * '''UI开发''':按钮点击、文本框输入 * '''游戏编程''':角色受伤、得分更新 * '''IoT系统''':传感器数据更新 * '''微服务''':领域事件通知 [[Category:C#编程]] [[Category:事件驱动编程]] [[Category:编程语言]] [[Category:C Sharp]] [[Category:C Sharp 属性与事件]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)