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

C# 匿名函数与Lambda表达式

本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正

1.匿名函数 

在 C# 中,匿名函数是一种没有名称的函数,可以直接在代码中定义和使用

匿名函数主要有两种形式:匿名方法和Lambda 表达式

它们通常用于简化代码,特别是在需要短小函数的地方,如回调函数或内联函数

1.1匿名函数的声明与调用

首先,必须要需要清楚的一点是:匿名函数不要脱离委托和事件来使用

所以,先声明一个委托:


//一个无参无返回值的委托函数
delegate void D();

再声明一个匿名函数:

delegate () {Console.WriteLine("这是一个委托函数");
};

然后添加到委托中:

你可以参考这篇文章,  C# 委托-CSDN博客

通过创建实例的方式去添加匿名函数,即 "new"

D d = new D(delegate () {Console.WriteLine("这是一个委托函数");
});

 

 也可以直接等于一个匿名函数,即“=”

D d = delegate () {Console.WriteLine("这是一个委托函数");
};

 有点茴香豆的茴有五种写法的感觉了哈哈

1.2 匿名函数有参数

首先,你可以知道c#自定义的一些泛型委托,这样可以更好的使用匿名函数

当匿名函数有参数时,可以直接在声明的括号中定义参数

Action<int,int> action =delegate (int x, int y) {Console.WriteLine(x*y);
};
action(1, 5);

1.3 匿名函数有返回值

还是,你可以知道c#自定义的一些泛型委托,这样可以更好的使用匿名函数

匿名函数的返回值直接return就可以了,编译器会自动判断,委托函数考虑的就很多了

Func<int, int> func = delegate (int x) {return x;
};
func.Invoke(1);

再举个例子:

1.4 匿名函数的缺点

当你的委托是多播委托时,也就是一个委托添加了多个匿名函数时,当需要删除一些函数的时候就乱了套了,没有名字怎么找?没法找!

2.Lambda表达式

Lambda和匿名函数可以看作是同一个东西,只是声明上更加简洁

ps:lambda表达式不是正则表达式,因为我看到有人不知道从哪里听来的还犟

2.1 无参无返回值的Lambda表达式

Action action = () => {Console.WriteLine("这是一个Lambda表达式的");  
};

 

可以理解为把delegate简化成了=>并且放在了括号后面

2.2 有参数

Action<int> action1 = (int a) => {Console.WriteLine(a);
};

2.3 有返回值

Func<int, string> func = (int a) => {return "123";
};

2.4 闭包

闭包是指一个函数和它的外部环境(变量)一起被捕获的情况

即使这个函数在定义它的作用域之外被调用,它仍然可以访问和修改这些外部变量

举个栗子:

如果我有一段代码是这么写的,返回值number是重复的,因为我每次调用都会释放掉中间变量count的内存

毫不意外,的结果

 

但是如果我想要保留count从而使得最终nmber递增,可以这么写: 

Func<int, Func<int>> makeCounter = (int C) => {int count = C;return () => ++count;
};var number = makeCounter(0);//该委托是有返回值的,所以可以用一个var变量去接收
Console.WriteLine(number()); //第一次调用
Console.WriteLine(number()); //第二次调用

得到的结果:

 

Q:为什么number()是一个方法?

A:因为我返回值是一个委托,而委托可以被函数装载

Q:“Var”是什么?

A:var 是 C# 中的隐式类型局部变量声明,它允许编译器根据右侧的初始化表达式自动推断变量的类型,使用 var 可以使代码更简洁,但也需要注意可读性

Q:为什么用“Var”

A:不用声明一个相对应参数的函数

Q:为什么结果递增了?

A:虽然number变量是在makeCounter函数内部定义的,但由于lambda表达式捕获了这个变量

所以即使在makeCounter函数执行完毕后,number变量仍然存在并且可以被访问和修改

图示流程: 

 

 闭包说白了就是可以利用lambda表达式的特性,抓住中间变量,从而不释放掉其内存

使得其变量值保留下来

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • GitHub 详解教程
  • 密码错误springboot也正常启动了
  • 基于重要抽样的主动学习不平衡分类方法ALIS
  • EXCEL 排名(RANK,COUNTIFS)
  • 【React】箭头函数:现代 JavaScript 的高效编程方式
  • AI数字人+城市交通大数据可视化平台,让交通管理与服务更简便、更智能
  • WebKit引擎:打造无缝响应式设计
  • Python的人脸识别程序
  • Go实用技巧
  • 微服务实战系列之玩转Docker(五)
  • 缓慢变化维
  • 银行卡二三四要素核验的多种应用场景
  • AIGC Kolors可图IP-Adapter-Plus风格参考模型使用案例
  • 全国区块链职业技能大赛国赛考题区块链应用后端功能开发
  • 怎么使用动态IP地址上网
  • 【翻译】babel对TC39装饰器草案的实现
  • Android Volley源码解析
  • gulp 教程
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • Joomla 2.x, 3.x useful code cheatsheet
  • leetcode-27. Remove Element
  • SQLServer之创建数据库快照
  • use Google search engine
  • Vue2.x学习三:事件处理生命周期钩子
  • vue的全局变量和全局拦截请求器
  • 高性能JavaScript阅读简记(三)
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 人脸识别最新开发经验demo
  • 日剧·日综资源集合(建议收藏)
  • 如何选择开源的机器学习框架?
  • 小而合理的前端理论:rscss和rsjs
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 转载:[译] 内容加速黑科技趣谈
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • Prometheus VS InfluxDB
  • 阿里云移动端播放器高级功能介绍
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ‌JavaScript 数据类型转换
  • (3) cmake编译多个cpp文件
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (web自动化测试+python)1
  • (二)测试工具
  • (三)SvelteKit教程:layout 文件
  • (十)c52学习之旅-定时器实验
  • (算法)求1到1亿间的质数或素数
  • (未解决)macOS matplotlib 中文是方框
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)Dubbo快速入门、介绍、使用
  • (原)Matlab的svmtrain和svmclassify
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)可以带来幸福的一本书
  • .htaccess配置重写url引擎