网站搭建类型海报设计网站免费

diannao/2026/1/25 10:50:37/文章来源:
网站搭建类型,海报设计网站免费,微网站 app 区别,WordPress post登录今天我们来聊一聊 C# 中的本地函数。本地函数是从 C# 7.0 开始引入#xff0c;并在 C# 8.0 和 C# 9.0 中加以完善的。引入本地函数的原因我们来看一下微软 C# 语言首席设计师 Mads Torgersen 的一段话#xff1a;Mads Torgersen#xff1a;我们认为这个场景是有用的 —— 您… 今天我们来聊一聊 C# 中的本地函数。本地函数是从 C# 7.0 开始引入并在 C# 8.0 和 C# 9.0 中加以完善的。引入本地函数的原因我们来看一下微软 C# 语言首席设计师 Mads Torgersen 的一段话Mads Torgersen我们认为这个场景是有用的 —— 您需要一个辅助函数。您仅能在单个函数中使用它并且它可能使用包含在该函数作用域内的变量和类型参数。另一方面与 lambda 不同您不需要将其作为第一类对象因此您不必关心为它提供一个委托类型并分配一个实际的委托对象。另外您可能希望它是递归的或泛型的或者将其作为迭代器实现。[1]正是 Mads Torgersen 所说的这个原因让 C# 语言团队添加了对本地函数的支持。本人在近期的项目中多次用到本地函数发现它比使用委托加 Lambda 表达式的写法更加方便和清晰。本地函数是什么用最简单的大白话来说本地函数就是方法中的方法是不是一下子就理解了不过这样理解本地函数难免有点片面和肤浅。我们来看一下官方对本地函数的定义本地函数是一种嵌套在另一个成员中的私有方法仅能从包含它的成员中调用它。 [2]定义中点出了三个重点本地函数是私有方法。本地函数是嵌套在另一成员中的方法。只能从定义该本地函数的成员中调用它其它位置都不可以。其中可以声明和调用本地函数的成员有以下几种方法尤其是迭代器方法和异步方法构造函数属性访问器事件访问器匿名方法Lambda 表达式析构函数其它本地函数举个简单的示例在方法 M 中定义一个本地函数 addpublic class C {public void M(){int result add(100, 200);// 本地函数 addint add(int a, int b) { return a b; }} } 本地函数都是私有的目前可用的修饰符只有 async、unsafe、static静态本地函数无法访问局部变量和实例成员 和 extern 四种。在包含成员中定义的所有本地变量和其方法参数都可在非静态的本地函数中访问。本地函数可以声明在其包含成员中的任意位置但通常的习惯是声明在其包含成员的最后位置即结束 } 之前。本地函数与Lambda表达式的比较本地函数和我们熟知的 Lambda 表达式 [3]非常相似比如上面示例中的本地函数我们可以使用 Lambda 表达式实现如下public void M() {// Lambda 表达式Funcint, int, int add (int a, int b) a b;int result add(100, 200); } 如此看来似乎选择使用 Lambda 表达式还是本地函数只是编码风格和个人偏好问题。但是应该注意到使用它们的时机和条件其实是存在很大差异的。我们来看一下获取斐波那契数列第 n 项的例子其实现包含递归调用。// 使用本地函数的版本 public static uint LocFunFibonacci(uint n) {return Fibonacci(n);uint Fibonacci(uint num){if (num 0) return 0;if (num 1) return 1;return checked(Fibonacci(num - 2) Fibonacci(num - 1));} } // 使用 Lambda 表达式的版本 public static uint LambdaFibonacci(uint n) {Funcuint, uint Fibonacci null; //这里必须明确赋值Fibonacci num {if (num 0) return 0;if (num 1) return 1;return checked(Fibonacci(num - 2) Fibonacci(num - 1));};return Fibonacci(n); } 命名本地函数的命名方式和类中的方法类似声明本地函数的过程就像是编写普通方法。Lambda 表达式是一种匿名方法需要分配给委托类型的变量通常是 Action 或 Func 类型的变量。参数和返回值类型本地函数因为语法类似于普通方法所以参数类型和返回值类型已经是函数声明的一部分。Lambda 表达式依赖于为其分配的 Action 或 Func 变量的类型来确定参数和返回值的类型。明确赋值本地函数是在编译时定义的方法。由于未将本地函数分配给变量因此可以从包含它的成员的任意代码位置调用它们。在本例中我们将本地函数 Fibonacci 定义在其包含方法 LocFunFibonacci 的 return 语句之后方法体的结束 } 之前而不会有任何编译错误。而 Lambda 表达式是在运行时声明和分配的对象。使用 Lambda 表达式时必须先对其进行明确赋值声明要分配给它的 Action 或 Func 变量并为其分配 Lambda 表达式然后才能在后面的代码中调用它们。在本例中我们首先声明并初始化了一个委托变量 Fibonacci 然后将 Lambda 表达式赋值给了该委托变量。这些区别意味着使用本地函数创建递归算法会更轻松。因为在创建递归算法时使用本地函数和使用普通方法是一样的; 而使用 Lambda 表达式则必须先声明并初始化一个委托变量然后才能将其重新分配给引用相同 Lambda 表达式的主体。变量捕获我们使用 VS 编写或者编译代码时编译器可以对代码执行静态分析提前告知我们代码中存在的问题。看下面一个例子static int M1() {int num; //这里不用赋值默认值LocalFunction();return num; //OKvoid LocalFunction() num 8; // 本地函数 }static int M2() {int num; //这里必须赋值默认值比如改为int num 0;下面使用 num 的行才不会报错Action lambdaExp () num 8; // Lambda 表达式lambdaExp();return num; //错误 CS0165 使用了未赋值的局部变量“num” } 在使用本地函数时因为本地函数是在编译时定义的编译器可以确定在调用本地函数 LocalFunction 时明确分配 num。因为在 return 语句之前调用了 LocalFunction也就在 return 语句前明确分配了 num所以不会引发编译异常。而在使用 Lambda 表达式时因为 Lambda 表达式是在运行时声明和分配的所以在 return 语句前编译器不能确定是否分配了 num所以会引发编译异常。内存分配为了更好地理解本地函数和 Lambda 表达式在分配上的区别我们先来看下面两个例子并看一下它们编译后的代码。Lambda 表达式public class C {public void M(){int c 300;int d 400;int num c d;//Lambda 表达式Funcint, int, int add (int a, int b) a b c d;var num2 add(100, 200);} } 使用 Lambda 表达式编译后的代码如下public class C {[CompilerGenerated]private sealed class c__DisplayClass0_0{public int c;public int d;internal int Mb__0(int a, int b){return a b c d;}}public void M(){c__DisplayClass0_0 c__DisplayClass0_ new c__DisplayClass0_0();c__DisplayClass0_.c 300;c__DisplayClass0_.d 400;int num c__DisplayClass0_.c c__DisplayClass0_.d;Funcint, int, int func new Funcint, int, int(c__DisplayClass0_.Mb__0);int num2 func(100, 200);} } 可以看出使用 Lambda 表达式时编译后实际上是生成了包含实现方法的一个类然后创建该类的一个对象并将其分配给了委托。因为要创建类的对象所以需要额外的堆heap分配。我们再来看一下具有同样功能的本地函数实现public class C {public void M(){int c 300;int d 400;int num c d;var num2 add(100, 200);//本地函数int add(int a, int b) { return a b c d; }} } 使用本地函数编译后的代码如下public class C {[StructLayout(LayoutKind.Auto)][CompilerGenerated]private struct c__DisplayClass0_0{public int c;public int d;}public void M(){c__DisplayClass0_0 c__DisplayClass0_ default(c__DisplayClass0_0);c__DisplayClass0_.c 300;c__DisplayClass0_.d 400;int num c__DisplayClass0_.c c__DisplayClass0_.d;int num2 Mg__add|0_0(100, 200, ref c__DisplayClass0_);}[CompilerGenerated]private static int Mg__add|0_0(int a, int b, ref c__DisplayClass0_0 P_2){return a b P_2.c P_2.d;} } 可以看出使用本地函数时编译后只是在包含类中生成了一个私有方法因此调用时不需要实例化对象不需要额外的堆heap分配。当本地函数中使用到其包含成员中的变量时编译器生成了一个结构体并将此结构体的实例以引用ref方式传递到了本地函数这也有助于节省内存分配。综上所述使用本地函数相比使用 Lambda 表达式更能节省时间和空间上的开销。本地函数与异常本地函数还有一个比较实用的功能是可以在迭代器方法和异步方法中立即显示异常。我们知道迭代器方法的主体是延迟执行的所以仅在枚举其返回的序列时才显示异常而并非在调用迭代器方法时。我们来看一个经典的迭代器方法的例子static void Main(string[] args) {int[] list new[] { 1, 2, 3, 4, 5, 6 };var result Filter(list, null);Console.WriteLine(string.Join(,, result)); }public static IEnumerableT FilterT(IEnumerableT source, FuncT, bool predicate) {if (source null) throw new ArgumentNullException(nameof(source));if (predicate null) throw new ArgumentNullException(nameof(predicate));foreach (var element in source)if (predicate(element))yield return element; } 运行上面的代码由于迭代器方法的主体是延迟执行的所以抛出异常的位置将发生在 string.Join(,, result) 所在的行也就是在枚举返回的序列结果 result 时显示如图如果我们把上面的迭代器方法 Filter 中的迭代器部分放入本地函数static void Main(string[] args) {int[] list new[] { 1, 2, 3, 4, 5, 6 };var result Filter(list, null);Console.WriteLine(string.Join(,, result)); }public static IEnumerableT FilterT(IEnumerableT source, FuncT, bool predicate) {if (source null) throw new ArgumentNullException(nameof(source));if (predicate null) throw new ArgumentNullException(nameof(predicate));//本地函数IEnumerableT Iterator(){foreach (var element in source)if (predicate(element))yield return element;}return Iterator(); } 那么这时抛出异常的位置将发生在 Filter(list, null) 所在的行也就是在调用 Filter 方法时显示如图可以看出使用了本地函数包装迭代器逻辑的写法相当于把显示异常的位置提前了这有助于我们更快的观察到异常并进行处理。同理在使用了 async 的异步方法中如果把异步执行部分放入 async 的本地函数中也有助于立即显示异常。由于篇幅问题这里不再举例可以查看官方文档。总结综上所述本地函数是方法中的方法但它又不仅仅是方法中的方法它还可以出现在构造函数、属性访问器、事件访问器等等成员中本地函数在功能上类似于 Lambda 表达式但它比 Lambda 表达式更加方便和清晰在分配和性能上也比 Lambda 表达式略占优势本地函数支持范型和作为迭代器实现本地函数还有助于在迭代器方法和异步方法中立即显示异常。相关链接https://github.com/dotnet/roslyn/issues/3911 C# Design Meeting Notes ↩︎https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/local-functions 本地函数 ↩︎https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions Lambda 表达式 ↩︎作者 技术译民 出品 技术译站https://ITTranslator.cn/END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站模板安装出现预先建设数据库各种网站开发工具

电源、时钟、复位是主板能正常工作的三大要素。主板在电源、时钟都正常后,复位系统发出复位信号,主板各个部件在收到复位信号后,同步进入初始化状态。如图7-11所示为复位电路的工作原理图,各个十板实现复位的电路不尽相同&#xf…

怎么制作网站上传wordpress 随机显示

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 1. 法一:指针法 解题思路 我们以每一个窗口来看,找…

免费商城网站模板企业网站建设及维护费用

博物馆是人们了解历史文化、传承文明的重要场所。而博物馆的藏品管理是博物馆的核心工作之一,对于展现博物馆的魅力、吸引观众的眼球有着至关重要的影响。并且博物馆藏品管理是一项复杂且专业的工作,它涉及到多个方面,包括但不限于藏品的收集…

哪个网站可以做兼职讲师wordpress 更改页面排版

因为您在调用 请求接口的函数如getLocaltion() 方法时没有订阅返回的 Observable,或者在订阅 Observable 时没有正确处理其响应。即要subscribe接口,并正确处理。因为Observables 是惰性执行的。这意味着如果您创建了一个 Observable 对象,但…

网站素材免费下载公司宣传册设计与制作图片

目录 二分图概念 二分图应用场景 如何判定一个图是否可以划分成二分图 证明 染色法 原理步骤 时间复杂度 算法思路 例子 匈牙利算法 概念 匈牙利使用算法前提,场景 时间复杂度 算法思路 例子 二分图概念 二分图是图论中的一个重要概念,指的是一个图的…

合肥做网站推广的公司国字型网站建设布局

对win8开发,上一节我们对win8进行了简单的介绍,这一节我们来瞧一瞧他的开发环境搭建。 前奏。 这里所讲的win8开发,主要是指Windows8 app store 上开发,及metro ui或叫morden ui 程序的开发。传统桌面应用程序,网站应…

网站建设最贵服务商如何在建设教育协会网站注册考试

quickrun 是一款rk3588 rknn多模型高效高并发部署软件 软件框架 采用session思想,可以定义多个session满足不同模型的义务需求。比如充电桩检测,垃圾分类,悬崖检测,模型共用一个摄像头,采用yolov5的模型。 采用消息…

一个域名多个网站门店推广是什么意思

console.log("嵌套函数中调用fn this值被赋给self" self o);这个输出会是 false。 在 JavaScript 中,比较两个对象是否相等时,实际上比较的是它们在内存中的引用地址,而不是它们的属性值。即使两个对象有相同的属性值&#xff…

宁波做网站优化哪家好网站收录怎么做

一、堆树的定义 堆树的定义如下: (1)堆树是一颗完全二叉树; (2)堆树中某个节点的值总是不大于或不小于其孩子节点的值; (3)堆树中每个节点的子树都是堆树。 当父节点的键…

网站切换中英文贵州最新消息今天

全世界只有3.14 % 的人关注了数据与算法之美近日,一份滴滴出行内部流传出来的财务数据显示,该公司2018年持续巨额亏损,全年亏损高达109亿元人民币。若消息属实,那将说明,自2012年滴滴成立以来就一直处于亏损状态&#…

营销网站怎样做有什么做任务拿钱的网站

首先要声明一点,zk集群中,leader服务器有着比较重要的存在,Follower 服务器只是处理非事务性请求,leader服务器主要负责事务性请求,Follower 服务器在遇到事务性请求以后还是会转发给leader服务器处理,所以…

富阳网站公司怎么注册一个域名

不管是component还是分文件编写的一个自定义组件,遵循如下: a:不管哪一级的子对象 都可以直接调根节点下的方法和属性 b:不管哪一级的子对象 调用非根节点的方法和属性,前面要加上该节点的id,即id.方法()或id.属性的形式 import QtQuick 2.…

齐鲁建设网站涂鸦智能深圳分公司

TCPDump是一个用于抓取网络数据包的命令行工具。它可以帮助网络管理员和开发人员分析网络流量、故障排除以及安全问题。下面是一些TCPDump的详细用法: 基本用法: 监听指定网络接口:tcpdump -i eth0通过IP地址过滤:tcpdump host 19…

钓鱼网站怎么制作html网站飘动广告代码

word List25 如果存在什么问题,欢迎批评指正!谢谢!

做平台好还是自己建网站网站建设及推广培训

以下内容转载: 网格生成,是把一个特定的研究区域分割成由许多很小的子区域(元素),以满足一些特定的要求。在理想的情况下,网格中的每个元素的形状和分布可以通过一种自动的网格生成算法来确定。 结构网格生成的代数网格生成法和…

网站开发遵循的原则酷家乐在线家装设计

layer-background-image语法:layer-background-image : none | url (url)参数:none :  无背景图url :  使用绝对或相对地址指定背景图像说明:设置或检索对象整个区域的背景图像。示例:code {position: absolute;top: 100px; lef…

iis发布网站无法访问网站模板 古典

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…

网页制作基础题莱芜网站优化怎么做

科技日新月异,虚拟现实不再局限于依赖头显来探索虚拟世界。数据手套的广泛应用使人们能够更轻松地与虚拟世界产生真实互动。在此之中,手势识别作为一种直观、自然的人机交互方式,受到了广泛关注。数据手套作为一种能够精确捕捉手指运动的人机…

企业网站制作的书潜江资讯网全部

Vue的组件化 Vue的组件化开发是一种将复杂的业务拆分为一个个独立的、可复用的组件的开发方式。组件化开 发的核心思想是将页面拆分成多个组件,每个组件依赖的CSS、JS、模板、图片等资源放在一起开发和维护 什么是跟组件 在Vue中,根组件(…

国外网站怎么做引流做网站需要用什么语言

9、“别有忧愁暗恨生”中的“忧”应写作“幽”。( )尺寸标注的组成中包含单位,尺寸线,尺寸文字,尺寸箭头目前常见的光纤通常为单模光纤,因为直径细,通信容量大。“给予,提供”的日语假名是( )。1010.( )在FX系列PLC功能指令中有符号P表示脉冲执行。20世纪70年代,设计出了()系统…