如何在C#9 中使用static匿名函数
作者:码农读书 发布时间:2022-06-21 01:44:03
目录
匿名方法的代价
C#9 中使用静态匿名方法
匿名函数 在 C# 中已经出现很多年了,虽然匿名函数用起来很爽,但代价是不小的,为了避免不必要那些你意想不到的内存分配,这就是为什么 C#9 中引入 static 匿名函数的原因,这篇文章我们将会讨论如何使用 静态匿名函数 以及为什么要用。
匿名方法的代价
匿名方法代价不低,因为它有 委托调用 方面的开销,什么意思呢?如果你的 lambda 里需要捕获封闭方法的局部变量或者参数,那么就会存在两种堆分配,一种是委托上的分配,另一种是闭包上的分配,如果你的 lambda 仅仅捕获一个封闭方法的实例状态,那么仅会有委托分配,如果你的 lambda 什么都不捕获或者仅捕获一个静态状态,那么就没有任何分配。
如果你有点懵的话,使用下面的例子加深理解。
int y = 1;
MyMethod(x => x + y);
上面代码的 lambda 中需要获取 y,所以就有了意想不到的堆分配,要想解决,可以将 y 定义为 const 或者 static 来避免这种不必要的分配开销,修改代码如下:
const int y = 1;
MyMethod(static x => x + y);
为了避免这种不必要和浪费内存的分配,可以在 lambda 上使用 static 关键词 及 变量上标注 const,值得注意的是,static 匿名函数不能访问封闭方法的局部变量和参数和 this 指针,但可以引用它的 静态方法 和 常量。
C#9 中使用静态匿名方法
先看一下例子:
public class Demo
{
private string formattedText = "{0} It was developed by Microsoft's Anders Hejlsberg in the year 2000.";
void DisplayText(Func<string, string> func)
{
Console.WriteLine(func("C# is a popular programming language."));
}
public void Display()
{
DisplayText(text => string.Format(formattedText, text));
Console.Read();
}
}
class Program
{
static void Main(string[] args)
{
new Demo().Display();
Console.Read();
}
}
上面的例子中,formattedText变量会被 DisplayText 方法中的 func 所捕获,这也就意味着它会产生你意料之外的内存分配,把程序跑起来之后,会看到如下的输出。
为了避免这种内存分配,你只需要做两件事。
formattedText 上标记 const。
lambda 上标记 static。
所以修改后的代码如下:
public class Demo
{
private const string formattedText = "{0} It was developed by Microsoft's Anders Hejlsberg in the year 2000.";
void DisplayText(Func<string, string> func)
{
Console.WriteLine(func("C# is a popular programming language."));
}
public void Display()
{
DisplayText(static text => string.Format(formattedText, text));
Console.Read();
}
}
现在就没有任何你意料之外的分配了,我想这也是你想要的。
现在你可以使用 static + const 组合来提升应用程序性能了,同时也可以有效的阻止在 lambda 中误用封闭方法中的局部变量和参数引发的不必要开销。
来源:https://mp.weixin.qq.com/s/xGD2TmzPo-4-cVhQu6Uz8g


猜你喜欢
- 本文实例讲述了Android编程实现的一键锁屏程序。分享给大家供大家参考,具体如下:据笔者了解,所有的Android手机都用电源键来手动锁屏
- ByteArrayInputStream介绍ByteArrayInputStream 是字节数组输入流。它继承于 InputStream。I
- 说明:此头像类似微信群组头像,整个头像由组内前N位人员的头像组合而成,可用网络或本地图片进行组合,最终显示为一个头像整体,看效果图:一、自定
- public class MainActivity extends Activity { private Handler hand
- SpringBoot默认的存放静态资源文件的位置是:注:SpringBoot中的src/main/resources/资源文件夹对应clas
- 一.优先队列的应用优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后
- 本文实例为大家分享了C#实现钟表程序设计的具体代码,供大家参考,具体内容如下工作空间:代码如下:using System;using Sys
- 处理提交数据1、提交的域名称和处理方法的参数名一致提交数据 : http://localhost:8080/hello?name=xiaoh
- 冒泡排序冒泡排序的思想:每次让当前的元素和它的下一个元素比较大小、如果前一个的元素大于后一个元素的话,交换两个元素。这样的话经历一次扫描之后
- 1、什么是线程及线程池线程是操作系统进行时序调度的基本单元。线程池可以理解为一个存在线程的池子,就是一个容器,这个容器只能存在线程。这个容器
- 熬夜写完,尚有不足,但仍在努力学习与总结中,而您的点赞与关注,是对我最大的鼓励!在一些本地化项目开发当中,存在这样一种需求,即开发完成的项目
- 前言java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也不能做出来非常好用,
- 什么是TaskScheduler?SynchronizationContext是对“调度程序(scheduler)&am
- 1、启动新Activty1.1、功能分析App功能在第一个Activity输入消息点击第一个Activity的发送按钮发送消息到第二个Act
- 安全发布对象在静态初始化函数中初始化一个对象引用将对象的引用保存到volatile类型域或者AtomicReference对象中将对象的引用
- @SpringBootApplication的使用1. Spring Boot 的核心1.1. 入口类和 @SpringBootApplic
- 1、悬浮窗的基本介绍悬浮窗,大家应该也不陌生,凌驾于应用之上的一个小弹窗,实现上很简单,就是添加一个系统级别的窗口,Android中通过Wi
- 前言在我们开发过程中,由于主流的架构都是采用前后端分离的方式,我们作为后端开发者需要为前段持续地提供运行在容器中最新代码,虽然可
- 布隆过滤器原理很简单:就是把一个字符串哈希成一个整数key,然后选取一个很长的比特序列,开始都是0,在key把此位置的0变为1;下次进来一个
- 之前给大家在博文中讲过如何通过eclipse快速搭建SSM开发环境,但相对而言还是有些麻烦的,今天玄武老师给大家介绍下如何使用Intelli