差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
csharp:系统关键字 [2025/11/28 11:09] – [关键词速查表] 张叶安csharp:系统关键字 [2025/11/28 11:12] (当前版本) – [5. Event (事件) 关键词] 张叶安
行 136: 行 136:
 double area = Tools.Pi * 10 * 10; // 不需要 new Tools() double area = Tools.Pi * 10 * 10; // 不需要 new Tools()
 </code> </code>
 +
 +
 +==== 5. Event (事件) 关键词 ====
 +
 +在 C# 中,**event** 关键词用于在类或对象中声明事件。事件允许类或对象在发生某些特定情况时通知其他类或对象。这是一种基于 **发布-订阅 (Publish-Subscribe)** 模式的机制。
 +
 +=== 1. 核心概念 ===
 +
 +  * **发布者 (Publisher)**:定义事件并决定何时触发事件的类。
 +  * **订阅者 (Subscriber)**:监听事件并在事件触发时执行特定操作的类。
 +  * **委托 (Delegate)**:事件底层的类型安全函数指针,定义了事件处理程序的签名。
 +
 +=== 2. 语法结构 ===
 +
 +声明一个事件通常包含两个步骤:
 +  - 1. 定义委托(或者使用系统内置的 `EventHandler`)。
 +  - 2. 使用 `event` 关键词声明事件变量。
 +
 +<code csharp>
 +public delegate void MyEventHandler(string message); // 1. 定义委托
 +public event MyEventHandler OnProcessCompleted;      // 2. 声明事件
 +</code>
 +
 +=== 3. 实战案例 ===
 +
 +以下是一个完整的控制台程序案例,模拟了一个视频编码器(发布者)和邮件服务(订阅者)。
 +
 +== 案例代码 ==
 +
 +<code csharp>
 +using System;
 +
 +namespace EventDemo
 +{
 +    // 1. 定义包含事件数据的类 (可选,但推荐)
 +    public class VideoEventArgs : EventArgs
 +    {
 +        public string Title { get; set; }
 +    }
 +
 +    // 2. 发布者:视频编码器
 +    public class VideoEncoder
 +    {
 +        // 声明事件:使用内置的 EventHandler<T> 泛型委托
 +        // 这里的 event 关键词是核心
 +        public event EventHandler<VideoEventArgs> VideoEncoded;
 +
 +        public void Encode(string title)
 +        {
 +            Console.WriteLine($"正在编码视频: {title}...");
 +            System.Threading.Thread.Sleep(1000); // 模拟工作
 +
 +            // 触发事件
 +            OnVideoEncoded(title);
 +        }
 +
 +        // 按照约定,创建一个受保护的虚方法来触发事件
 +        protected virtual void OnVideoEncoded(string title)
 +        {
 +            // 检查是否有订阅者 (VideoEncoded != null)
 +            VideoEncoded?.Invoke(this, new VideoEventArgs { Title = title });
 +        }
 +    }
 +
 +    // 3. 订阅者:邮件服务
 +    public class MailService
 +    {
 +        // 事件处理程序:签名必须与委托匹配
 +        public void OnVideoEncoded(object source, VideoEventArgs e)
 +        {
 +            Console.WriteLine($"邮件服务:发送邮件,视频 '{e.Title}' 编码完成。");
 +        }
 +    }
 +
 +    // 4. 主程序
 +    class Program
 +    {
 +        static void Main(string[] args)
 +        {
 +            var video = new VideoEncoder(); // 发布者
 +            var mailService = new MailService(); // 订阅者
 +
 +            // 订阅事件:使用 += 操作符
 +            video.VideoEncoded += mailService.OnVideoEncoded;
 +
 +            video.Encode("复仇者联盟");
 +        }
 +    }
 +}
 +</code>
 +
 +== 输出结果 ==
 +
 +<code text>
 +正在编码视频: 复仇者联盟...
 +邮件服务:发送邮件,视频 '复仇者联盟' 编码完成。
 +</code>
 +
 +=== 4. 关键点总结 ===
 +
 +  * **封装性**:`event` 关键词为委托实例提供了一层封装。在类的外部,客户端只能使用 `+=` (订阅) 和 `-=` (取消订阅),而不能直接使用 `=` 赋值(这会覆盖其他订阅者)或直接调用 `Invoke()`。
 +  * **空检查**:在触发事件前,务必检查事件是否为 `null`(即是否有订阅者),C# 6.0 以后推荐使用 `?.Invoke()`。
 +  * **命名规范**:事件通常命名为 `Name` 或 `OnName`,处理方法通常命名为 `OnName`。

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • csharp/系统关键字.1764299381.txt.gz
  • 最后更改: 2025/11/28 11:09
  • 张叶安