如何利用 C# 内置的 Action 和 Func 委托

上一篇已经理解了委托的本质,我们就可以进入 C# 开发的"实战区"。

在现代 C# 开发中,我们很少再手动声明 delegate 关键字,而是直接使用微软提供的"全家桶":Action 和 Func。

1. 利用内置委托简化代码:Action 与 Func

这两个内置委托几乎覆盖了 99% 的应用场景,它们的区别非常简单:

  • Action :用于没有返回值 的方法(void)。
  • Func :用于有返回值的方法。

简化对比

如果不使用内置委托,你需要先声明再使用;使用后,代码变得极其紧凑。

场景 传统自定义委托 使用 Action/Func (推荐)
无返回值 delegate void Log(string s); Action<string>
有返回值 delegate int Calc(int x, int y); Func<int, int, int> (最后一个是返回值类型)

实例代码

csharp 复制代码
// Action: 接收一个 string,返回 void
Action<string> logger = message => Console.WriteLine(message);
logger("Action 执行成功");

// Func: 接收两个 int,返回一个 int
// 语法:Func<参数1, 参数2, 返回值类型>
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 10); // result = 15

2. 深入分析:委托在"事件(Event)"中如何工作

事件(Event)本质上是对委托的"封装"或"保护层"。

如果把委托比作一个"公开的呼叫名单",任何人都可以擦除或修改名单;那么事件就是"带锁的通知公告栏"------你只能订阅(+=)或取消订阅(-=),但不能清空整个名单(= null),也不能替主人发布消息。

事件的底层机制:发布-订阅模式

  1. 发布者(Publisher): 拥有委托,并决定何时触发它。
  2. 订阅者(Subscriber): 向委托注册自己的方法。

为什么需要 Event 而不是直接用 Delegate?

  • 安全性: 在类外部,event 只能使用 += 和 -=。你不能在类外部直接调用 myEvent(),也不能通过 myEvent = null 把别人的订阅给抹除。
  • 职责分离: 事件确保只有拥有者才能触发通知。

3. 事件工作流程实例

让我们模拟一个"闹钟"场景:

csharp 复制代码
using System;

// 1. 定义事件参数(习惯做法:继承 EventArgs)
public class AlarmEventArgs : EventArgs {
    public string Message { get; set; }
}

public class AlarmClock {
    // 2. 声明事件(使用内置的 EventHandler 委托类型)
    // 这本质上是一个受保护的委托
    public event EventHandler<AlarmEventArgs> AlarmTriggered;

    public void StartAlarm() {
        Console.WriteLine("闹钟正在倒计时...");
        System.Threading.Thread.Sleep(1000);
        
        // 3. 触发事件(发布通知)
        // ?. 表示如果没有人订阅,就不执行
        AlarmTriggered?.Invoke(this, new AlarmEventArgs { Message = "起床啦!" });
    }
}

class Program {
    static void Main() {
        AlarmClock clock = new AlarmClock();

        // 4. 订阅事件 (使用 +=)
        clock.AlarmTriggered += (sender, e) => {
            Console.WriteLine($"收到通知: {e.Message}");
        };

        clock.StartAlarm();
    }
}

核心总结

  1. Action/Func 是委托的常用"模板",让我们省去了定义类型的麻烦。
  2. 委托 (Delegate) 是底层工具,提供了"方法指针"的能力。
  3. 事件 (Event) 是高级包装,它利用委托实现了安全的、受限的观察者模式。
相关推荐
半摆烂日常几秒前
手机表单的左滑操作:触摸事件的处理细节
大数据·开发语言·人工智能·智能手机·https·c#
星夜离尘5611 分钟前
MATLAB滑动RMS如何接报警:窗口未满和缺样不能当成正常
开发语言·matlab
开开心心就好18 分钟前
白天晚上自动调蓝光,护眼工具亮度可调
服务器·开发语言·算法·pdf·ocr·intellij-idea·idea
张张123y19 分钟前
后端第十一课:RAG 落地实战(从 0 到 1 接上私有知识库,并设计一个好用的 RAG)
开发语言·人工智能·python·机器学习·fastapi·rag
梅梅绵绵冰21 分钟前
JVM虚拟机
java·开发语言·jvm
绛橘色的日落(。・∀・)ノ26 分钟前
C#学习笔记
笔记·学习·c#
asdzx6734 分钟前
C# 将 HTML 转换为 PDF:基于 Chrome 的转换方案
pdf·c#·html
Shaoshing1 小时前
消息顺序
java·开发语言
云水初1 小时前
【项目篇】基于LanGraph的自动处理客服邮件的 Agent汇总
开发语言·笔记·python·学习·fastapi·langgraph
茉莉玫瑰花茶1 小时前
GO [ 内存与变量逃逸分析 ]
开发语言·后端·golang