当前位置: 首页 > news >正文

Func和Action委托简单用法

Func和Action类是特殊的类型,它们允许你在不必指定自定义委托类型的情况下,去使用委托。在整个.NET框架中都可以使用它们。例如,在我们考察并行计算时,你也会看到这两个类的示例。

上面一段文字是官方的一段翻译。虽然看上去你不太容易能理解是什么意思。的确委托糅合C#的很多概念在里面,一时半会要真正理解其含义用途不是一件现实的事情。说实在的,我也是经历很长的时间才理解委托的用途的,虽然不太全面。
网上关于C#委托的文章很多,大多数都只是说清楚了如何使用委托,但并未解释为什么它们是有用的。当然这篇文章也只是介绍Func和Action的简单用法,如果你想对委托有更深刻的理解,我推荐看看这篇文章 http://www.cnblogs.com/r01cn/archive/2012/11/30/2795977.html

还是用简单的语法快速地学会在C#中如何使用Action和Func。(看完之后,比你想象中要简单N倍)

Action的用法

我们定义没有返回值没有参数的委托这样的:

   private delegate void EatRice(); //定义一个eatrice委托类型
写一个无返回值无参数的函数:

        private static void  Eat()
        {
            Console.WriteLine("我吃饭了");
        }
然后声明并调用:
        static void Main(string[] args)
        {
            EatRice eatRice =Eat;//实例化委托类型
            eatRice();//调用委托
        }
问题来了:有没有办法不定义委托,直接调用呢?当然是可以的,直接用Action

Action是.net 内置的委托(F12之后有种被骗的感觉),有很16个重载,低版本好像没这么多

        static void Main(string[] args)
        {
            Action eat = Eat;
            eat();
        }
        private static void  Eat()
        {
            Console.WriteLine("我吃饭了");
        }

还有Action<T> 委托,说是有16个“重载”(其实这种说法不正确),也就是可以最多可以接收16个 T类型的参数
演示一下Action<T,T> 接收两个T类型的参数委托(Action的委托重点是一定没有返回值类型)

        static void Main(string[] args)
        {
            Action<int ,string> eat = Eat;
            eat(5,"苹果");
        }
        private static void  Eat(int  num,string  name)
        {
            Console.WriteLine($"我吃了{num}个{name}");
        }
我们F12转到定义看看,结果有点失望,原来也就是用delegate 关键字定义一个Action的名称。国际惯例,还是发张图


可以接匿名函数使用吗?当然是可以的, lambda表达式也是可以的

        static void Main(string[] args)
        {
            Action<int ,string> eat = delegate(int x,string  name) {
                Console.WriteLine($"我吃饭{x}个{name}");
            };
            eat(5,"苹果");
        }
lambda表达式:

     Action<int, string> eat = (num, name) =>
            {
                Console.WriteLine($"我吃饭{num}个{name}");
            };
           eat(5,"苹果");

虽然上面只是告诉我们Action如何使用,但是并没有说明它的作用体现在哪里。写一个发送请求的方法你就会知道它是有作用的

        static void Main(string[] args)
        {
            sendPost(success => { Console.WriteLine(success); },//实现响应成功做哪些事情
                errorAction => { Console.WriteLine(errorAction); });//实现失败做哪些事情
        }
        private static void sendPost(Action<string>  errorAction,Action<string> successAction)
        {
            
            bool resSuccess = true;//发送请求,接收数据是否成功
            string errorCode = "1004";
            if (resSuccess)
            {
                successAction("响应成功");
            }
            else
            {
                errorAction("响应失败,errorCode"+errorCode);
            }

使用发送请求方法的时候,将Action委托作为参数去实现。这有点类似jquery的ajax 方法 error,success去回调。

Action 的委托没有返回值,那要是有返回值的函数怎么做,恰恰相反Func就是专门解决这样一个事情的必须有返回值参数(0-16 T类型参数)

Func的用法

在不使用Func委托时我们来写一个计算两个int类型乘积的委托返回值是int。

        private delegate int Calc(int a,int b); //定义一个Calc委托类型 ,计算a*b
        static void Main(string[] args)
        {
            Calc calc = calcMul;//实例化委托
            Console.WriteLine(calc(10,12));        //调用委托
        }
        private static int calcMul(int  a ,int b)
        {
            return a * b;
        }

不使用delegate关键字声明委托直接使用内置写好的Func关键字这样就OK了。

        static void Main(string[] args)
        {
            Func<int, int, int> calc = calcMul;
            Console.WriteLine( calc(12,45));
        }
        private static int calcMul(int  a ,int b)
        {
            return a * b;
        }
Func至少有一个T类型参数作为返回值。规定是将最后一个参数作为返回值。
Func结合匿名方法和lambda表达式也是可以的。
        static void Main(string[] args)
        {
            Func<int, int, int> calc = delegate (int x, int y)
            {
                return x * y;
            };
            Console.WriteLine(calc(10,45));
        }
lambda表达式:

     static void Main(string[] args)
        {
            Func<int, int, int> calc =(x,y)=>
            {
                return x * y;
            };
            Console.WriteLine(calc(10,45));
        }

至于Func为什么是很有作用,这个就不多写了,和Action差不多,委托还需要在实践中不断使用,就会发现这两个玩意的经典之处。

的确,是不是比想象中要简单许多。.net 中随处可见委托,不会玩委托真的挺尴尬的。写的有点杂,没有说到的地方,还请各位见谅。

作者:张林

标题: 原文地址:http://blog.csdn.net/kebi007/article/details/69367562

转载随意注明出处


转载于:https://www.cnblogs.com/zhangmumu/p/7374777.html

相关文章:

  • APMServ错误解决办法:1、Apache启动失败,请检查相关配置
  • iptables配置详解
  • wordpress如何安装主题?
  • Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace 解决方法...
  • flex不能生成swf和html
  • java中各种date格式的转化
  • eclipse+maven搭建web工程之创建
  • 一类积性函数的前缀和---刷题记录
  • AS3教程:for each in解析效率
  • [4.9福建四校联考]
  • flex教程:一个虚线画法实例
  • git分支小问题
  • flex教程:flex4破解,以及序列号防止过期
  • flex教程:内存使用机巧
  • 几个简单的数字问题引发的对计算机逻辑的浅显思考,细思有味。新手帖,高手勿砖。...
  • 〔开发系列〕一次关于小程序开发的深度总结
  • css系列之关于字体的事
  • Gradle 5.0 正式版发布
  • Swift 中的尾递归和蹦床
  • swift基础之_对象 实例方法 对象方法。
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 类orAPI - 收藏集 - 掘金
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 全栈开发——Linux
  • 如何合理的规划jvm性能调优
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #Java第九次作业--输入输出流和文件操作
  • (02)vite环境变量配置
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (MATLAB)第五章-矩阵运算
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (原創) 物件導向與老子思想 (OO)
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转)原始图像数据和PDF中的图像数据
  • 、写入Shellcode到注册表上线
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .net6Api后台+uniapp导出Excel
  • .net连接MySQL的方法
  • @Autowired标签与 @Resource标签 的区别
  • []FET-430SIM508 研究日志 11.3.31
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • [AutoSar NVM] 存储架构
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [C语言]——柔性数组
  • [DevEpxress]GridControl 显示Gif动画
  • [flask] flask的基本介绍、flask快速搭建项目并运行
  • [Jenkins] Docker 安装Jenkins及迁移流程
  • [linux] 创建用户
  • [LOJ161] 仙人掌计数
  • [Machine Learning][Part 7]神经网络的基本组成结构