如何利用 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) 是高级包装,它利用委托实现了安全的、受限的观察者模式。
相关推荐
一晌小贪欢24 分钟前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck1 小时前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
一条大祥脚1 小时前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
FRing032 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
旖旎夜光2 小时前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
starzy19902 小时前
深入理解Scala嵌套函数:作用域封装之道
开发语言·scala
Sakura_j_h_3 小时前
从零写一个 MCP stdio Server:用 Python 校验博客文章格式
开发语言·python·自动化·ai工具·mcp·json-rpc
白杨尚青4 小时前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
.道阻且长.4 小时前
Linux基本开发工具:gdb和cgdb的使用
linux·运维·服务器·开发语言
starzy19905 小时前
深入理解Scala匿名函数:函数式编程基石
开发语言·scala