当前位置: 首页 > 编程语言 > C#

显式本地作用域-有什么实际好处吗?分享

时间:2023-04-10 20:25:33 C#

清晰的局部范围——有什么真正的好处吗?我正在清理一些代码并删除不再需要的if语句。但是,我意识到我忘了删除括号。这当然有效,它只是创建一个新的本地范围。现在这让我开始思考。在我多年的C#开发中,我从未遇到过使用它们的理由。事实上,我有点忘了我可以。定义本地范围有什么实际好处吗?我知道我可以在一个范围内定义变量,然后在不相关的范围(for、foreach等)中再次定义相同的变量,如下所示:voidSomeMethod(){{inti=20;}诠释我=50;//无效,因为上面已经使用了i。}voidSomeMethod2(){{inti=20;}{整数我=50;//由于范围不相关而有效。}{字符串i="ABCDEF";}}定义局部作用域的真正意义是什么?实际上是否有任何形式的性能提升(或潜在损失)?我知道您可以在C++中执行此操作,并且是帮助您管理内存的一部分,但由于这是.NET,真的会有好处吗?这只是语言的双重乘积吗,即使没有真正的好处,我们是否可以定义随机范围?在C#中,将一组语句转换为单个语句纯粹是语法问题。对于需要跟在单个语句之后的任何关键字都是必需的,例如if、for、using等。一些边缘情况:使用它来限制局部变量的范围是一个失败的原因。这在C++中是一个大问题,因为右大括号是编译器将在作用域块内注入变量的析构函数调用的地方。对于一直被滥用/使用的RAII模式,没有什么比在程序中使用标点符号具有如此剧烈的副作用更可靠的了。C#团队对此没有太多选择,局部变量的生命周期由抖动严格控制。这忽略了方法中的任何分组构造,它只知道IL。除了try/except/finally之外没有分组结构。任何局部变量的作用域,无论写在哪里,都是方法体。当您在已编译的C#代码上运行ildasm.exe时,您会看到一些东西,您会看到局部变量被提升到方法体的顶部。这部分还解释了为什么C#编译器不允许您在另一个同名范围块中声明另一个局部变量。Jitter有关于局部变量生命周期的有趣规则,它们完全由垃圾收集器的工作方式决定。当它运行一个方法时,它不仅会生成该方法的机器码,还会创建一个表来描述每个局部变量的实际作用域、初始化它的代码地址以及不再使用它的代码地址。垃圾收集器使用此表根据活动执行地址确定对对象的引用是否有效。这使得它在收集对象方面非常有效。当你在与本地代码进行互操作时,有时它过于高效和繁琐,你可能需要神奇的GC.KeepAlive()方法来延长生命周期。这是一种非常酷的方法,根本不会生成任何代码。它的唯一用途是让抖动改变表并为变量的生命周期插入一个更大的地址。就像函数一样,这些“块”几乎只是用于隔离(大部分)不相关的代码区域及其在函数内的局部变量。例如,如果你需要一些临时变量在两个函数调用之间传递,你可以使用它intFoo(inta){//...{inttemp;SomeFuncWithOutParam(a,outtemp);NowUseThatTempJustOnce(温度);错误地尝试使用(温度);//不编译!//...}然而,如果您需要这种词法范围,有人可能会争辩说内部块应该是它们自己的函数。至于表演等,我非常怀疑它是否重要。编译器将函数视为一个整体,并在确定堆栈帧大小时收集所有局部变量(甚至是内联声明的变量)。所以基本上所有局部变量都集中在一起。使用你的变量来给你一点约束是纯粹的词汇。局部范围可能有用的地方:在switch语句的case语句中。默认情况下,所有情况都与switch语句共享相同的范围。不允许在多个case语句中声明同名的局部临时变量,您最终只能在第一个case语句中甚至在switch语句之外声明该变量。您可以通过为每个case语句提供一个局部作用域并在该作用域内声明临时变量来解决这个问题。但是,在不使您的情况过于复杂的情况下,这个问题可能表明最好调用一个单独的方法来处理case语句。它的优点主要是使语言的定义更加简单。定义现在可以简单地说if、while、for等......应该跟一个声明。括号中的一组语句只是一个可能的语句。在您的示例中使用禁止语句块并没有真正的好处。有时他们会避免名称冲突,但您可以在没有名称冲突的情况下解决问题。与C、C++和Java等语言相比,它还不必要地引入了语法规则差异。如果您想知道它也不会更改引用对象的对象生命周期。至少在发布模式下,不会有性能提升:如果一个对象知道——或者至少认为——它将不再被使用,那么无论作用域如何,它都可以被回收。这可能会阻止您管理互操作:http://blogs.msdn.com/b/oldnewthing/archive/2010/08/13/10049634.aspx。也就是说,我不时使用这个“功能”来确保某些临时对象不能被代码隐藏使用。在大多数情况下,它可能可以通过分解成其他方法来完成,但有时您会变得不必要地笨拙,或者由于某些原因(例如在您设置只读成员的构造函数中)不可能实现。有一段时间我用它来重用变量名,但这通常与“临时对象”的原因相结合。这就是C#学习教程:显式局部作用域-有什么真正的好处吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: