惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
爱范儿
爱范儿
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
罗磊的独立博客
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
D
DataBreaches.Net
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy & Cybersecurity Law Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog
V
Vulnerabilities – Threatpost
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
T
Tor Project blog
GbyAI
GbyAI
Recent Announcements
Recent Announcements
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
G
GRAHAM CLULEY
宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
C
Check Point Blog
W
WeLiveSecurity
F
Fortinet All Blogs
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
月光博客
月光博客
Project Zero
Project Zero
Know Your Adversary
Know Your Adversary
V
Visual Studio Blog
H
Help Net Security
H
Hacker News: Front Page
Webroot Blog
Webroot Blog
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
O
OpenAI News
The Cloudflare Blog
Attack and Defense Labs
Attack and Defense Labs

宏尘极客

halo-theme-dream2.0-plus 主题-新版朋友圈配置说明 halo-theme-dream2.0-plus 主题 1.20.2 版本-留言板配置说明 微信红包封面-马到功成 Windows11彻底关闭自动更新指南 WSL2 Docker 资源配置指南 绿联Pro 安装Dos游戏中文版webui,一个可以浏览器内玩dos游戏的容器 绿联Pro 安装 Stirling-PDF-V2 - 强大的本地托管基于 Web 的 PDF 操作工具 绿联Pro 部署在线游戏机 绿联Pro 安装OpenList一个支持多种存储的文件列表程序 绿联Pro 部署Memos - 轻量级自托管备忘录中心 绿联Pro 安装 Stirling-PDF - 强大的本地托管基于 Web 的 PDF 操作工具 绿联Pro 部署Upage - 基于大模型的可视化网页构建平台,Lovable 开源替代 不蒜子数据同步工具使用指南 绿联Pro 部署 PostgreSQL 数据库 绿联Pro 自建不蒜子统计服务,替代Dream2.0 Plus主题页脚统计数据 1panel使用编排模板部署不蒜子服务,自建不蒜子统计服务,替代Dream2.0 Plus主题页脚统计数据 绿联Pro 安装Photopea,轻量在线PS工具 绿联Pro 安装禅道(Zentao),一款功能强大、全面的敏捷项目管理软件 绿联Pro 安装MeterSphere,新一代的测试管理和接口测试工具 Docker Compose 标签介绍与示例指南 绿联Pro 安装Meilisearch 搜索引擎,为halo博客提供增强搜索引擎 解析 <meta> 标签的全局 Referrer 策略设置 电线粗细选择与家用大功率电器布线指南 Nginx 防盗链配置介绍 Nginx 反向代理简介 绿联Pro 部署meting-api服务并使用lukcy反向代理,自建音乐API服务 1panel使用编排模板部署meting-api服务,自建音乐API服务 java开发 - 通过客户端访问接口获取接口服务器实际部署地址 Git revert 撤销已推送到服务器的提交详解 绿联Pro 部署MediaGo,跨平台视频提取工具 绿联Pro 安装Umami,使用MySQL数据库,为你的网站添加网站监控
C# 自定义事件与委托
宏尘 · 2025-05-18 · via 宏尘极客

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. 总结

  • 委托:方法的容器,可以存储和调用一个或多个方法

  • 事件:基于委托的机制,用于实现发布-订阅模式

  • 自定义事件步骤

    1. 定义事件参数类(继承自 EventArgs)

    2. 定义委托(或使用内置的 EventHandler)

    3. 在类中声明事件

    4. 编写触发事件的方法

    5. 订阅事件并处理

记住:事件让我们的代码可以"通知"其他部分发生了某些事情,而不需要知道谁会处理这些事件!