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

推荐订阅源

D
Docker
博客园 - 【当耐特】
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
大猫的无限游戏
大猫的无限游戏
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Fortinet All Blogs
Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
J
Java Code Geeks
Engineering at Meta
Engineering at Meta
MyScale Blog
MyScale Blog
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理

博客园 - 火冰·瓶

Cloudflare Tunnel 有两种模式 用 Cloudflare Tunnel 实现从外网 SSH 登录内网服务器 Cloudflare + .NET Core MVC 部署完整流程 net core 后端获取网络图片的扩展名 推荐好用的web控件 ubuntu运维 使用Frp+Caddy把https映射到内网的web服务 net core中结合EntityFrameworkCore的DB first使用PostgreSQL OneDrive中设置不同步某个文件夹 Framework 4.7老项目运行到caddy EF Core经验 net core随记 asp.net core 记录页面访问次数,同一个IP一个小时只算一次 asp.net core 记录页面访问记录 asp.net core 发布到caddy asp.net core发布到Caddy获取用户的真实ip 统计文章阅读量,一小时内重复刷新的不重复统计 使用on()方法绑定事件,解决动态加载的元素事件绑定 鼠标悬停在图片上方时,显示文字
Action<T> 和 Func<T>的用法
火冰·瓶 · 2025-04-24 · via 博客园 - 火冰·瓶

在 C# 中,Action<T>Func<T> 都是 泛型委托,用于引用方法,但它们的主要区别在于 是否有返回值

Action<T> 用于 执行某个操作,但 不返回任何值

Func<T> 用于 执行某个操作并返回结果,最后一个参数是返回值

Action<string> logMessage = msg => Console.WriteLine($"日志: {msg}");
// 执行委托
logMessage("系统启动"); // 输出: 日志: 系统启动
//
//等同于
public void logMessage(string msg)
{
        Console.WriteLine($"日志: {msg}");
}


/*************************************************/

Action<string, int, long> logInfo = (message, code, timestamp) =>
{
          Console.WriteLine($"日志信息: {message}, 错误码: {code}, 时间戳: {timestamp}");
};

// 执行委托
logInfo("系统错误", 404, DateTimeOffset.UtcNow.ToUnixTimeSeconds());
//等同于
public void logInfo(string message, int  code, long timestamp)
{
         Console.WriteLine($"日志信息: {message}, 错误码: {code}, 时间戳: {timestamp}");
}

实例点典型应用一

类库中某个方法需要调用ILogger写入日志,但是ILogger是在Controller中依赖注入实例化,类库中无法调用,这个时候在类库中的这个方法上多加一个参数Action<string> log (可选参数Action<string>? log = null)

//假如类库中原方法为:
public void SendSms(string phone, string code)
{
}
//修改为:
public void SendSms(string phone, string code, Action<string>? log = null)
{
     //其他代码
     log("日志内容xxxx");
     //其他代码
}

//然后在Controller中定义个符合 Action<string>规范的方式如下:
private void Log(string msg)
{
       _logger.LogInfo(msg);
}

//原来的
SendSms(phone,code);
//修改为:
SendSms(phone, code, Log);
//或者直接用Lambda表达式简写
SendSms(phone, code, msg=>{_logger.LogInfo(msg);});

实例点典型应用二

静态类库AlibabaSMSService中定义了一个方法,包含Action<T>参数

//Action<SmsRecord> saveRecord,定义了一个saveRecord方法,有一个对象参数SmsRecord
   public void SendSms(string phone, string code, Action<SmsRecord> saveRecord)
   {
                SmsRecord smsRecord = new SmsRecord
                {
                    Code = code,
                    SendTime = DateTime.Now,
                    Phone = phone,
                    SignName = sendSmsRequest.SignName,
                    TemplateCode = sendSmsRequest.TemplateCode,
                    TemplateParam = sendSmsRequest.TemplateParam,
                    ResponseMsg = $"Message:{response.Body.Message},Code:{response.Body.Code}"
                };
                saveRecord(smsRecord);
   }

在Controller中调用  

                AlibabaSMSService.SendSms(tel, smsCode, 
                async x =>
                {
                    //这里x是SmsRecord,可以继续赋值
                    x.Ip = Request.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "Unknown";
                    x.VisitId = _vistId;
                    x.SmsTypeStr=SmsType.RegisterCode.ToString();
                    await smsDAL.AddSmsRecord(x);  //smsDAL.AddSmsRecord(x)是异步方法
                }
                 );