明确本地作用域的 - 任何真正的好处? [英] Explicit Local Scopes - Any True Benefit?

查看:81
本文介绍了明确本地作用域的 - 任何真正的好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是清理一些代码,删除了不再需要一个如果语句。但是,我意识到我忘了删除括号。这当然是有效的,就创建了一个新的本地范围。现在,这个让我思考。在我多年C#开发的,我从来没有碰到过一个理由来使用它们。其实,我有点忘了我能做到这一点。

I was cleaning up some code and removed an if statement that was no longer necessary. However, I realized I forgot to remove the brackets. This of course is valid and just created a new local scope. Now this got me thinking. In all my years of C# development, I have never come across a reason to use them. In fact, I kind of forgot I could do it.

有没有定义一个局部范围的任何实际的好处?我明白我可以在一个范围内定义变量,然后在一个不相关的范围内再次定义的相同(平的foreach等),象下面这样:

Is there any actual benefit to defining a local scope? I understand I can define variables in one scope and then define the same ones again in an unrelated scope (for, foreach, etc.) like below:

void SomeMethod()
{    
    {
        int i = 20;
    }

    int i = 50; //Invalid due to i already being used above.
}

void SomeMethod2()
{    
    {
        int i = 20;
    }
    {
        int i = 50; //Valid due to scopes being unrelated.
    }
    {
        string i = "ABCDEF";
    }
}



什么是定义一个局部范围内的真正意义呢?可这里居然是任何类型的性能提升(或潜在亏损)?我知道你可以在C ++中做到这一点,是帮助您管理内存的一部分,但因为这是.NET,就真的是有什么好处?那是让我们定义随机范围,即使没有真正的好处的语言这只是一个副产品?

What's the true point of defining a local scope? Can there actually be any sort of performance gain (or potentially a loss)? I know you could do this in C++ and was part of helping you manage memory, but because this is .NET, would there really be a benefit? Is this just a bi-product of the language that let's us define random scopes even though there is no true benefit?

推荐答案

在C#中,它纯粹是语法将一组语句组合成一个语句。需要对于预期单个语句跟随,就像如果,因为,使用等几个角落案件的任何关键字:

In C#, it is purely syntax to turn a group of statements into a single statement. Required for any keyword that expects a single statement to follow, like if, for, using, etc. A few corner cases:


  • 开关内部的情况下的关键字是特殊的,因为它不要求它是一个单一的声明。在破解转到的关键字重圆。这也解释了为什么你可以在变量声明中使用括号卡纸。

  • 中的尝试的和的的关键字是特殊的,他们的要求的括号即使只有一条语句如下。非常不寻常,但可能迫使程序员考虑一下声明的块内的范围启发,catch块不能引用变量try块内,因为这样的异常处理的作品。

  • the case keyword inside a switch is special since it doesn't require it to be a single statement. The break or goto keyword ends it. Which explains why you can use braces to jam in a variable declaration.
  • the try and catch keywords are special, they require braces even if only a single statement follows. Pretty unusual but probably inspired by forcing the programmer to think about the scope of declarations inside the blocks, a catch block cannot refer to variables inside the try block because of the way exception handling works.

限制它的局部变量的作用域是一个失败的事业。这是一个在C大不了++,因为结束括号就是编译器将注入的范围块中的变量析构函数调用的地方。这是AB /使用的所有时间RAII模式,没有什么可怕的漂亮有关程序有标点有如此激烈的副作用。

Limiting the scope of local variables with it is a lost cause. It is a big deal in C++ because the ending brace is the place where the compiler will inject destructor calls for variables inside the scope block. This is ab/used all the time for the RAII pattern, nothing terribly pretty about having punctuation in a program have such drastic side-effects.

C#团队没有有很多的选择一下的,局部变量的生命周期由抖动受到严格控制。这是无视的方法中的任何分组构造,只知道IL。它不具有任何分组构造以外的try /除外/最后。任何局部变量,不管它是书面的,范围是方法的主体。东西当你在编译的C#代码运行程序Ildasm.exe你可以看到,你会看到悬挂的方法体顶部的局部变量。这也部分解释了为什么C#编译器不会让你声明与另一个同名的范围块另一个局部变量。

The C# team didn't have a lot of choice about it, the life-time of local variables is strictly controlled by the jitter. Which is oblivious to any grouping constructs inside a method, it only knows about IL. Which doesn't have any grouping constructs beyond try/except/finally. The scope of any local variable, no matter where it was written, is the body of the method. Something you can see when you run ildasm.exe on compiled C# code, you'll see the local variables hoisted to the top of the method body. Which partly also explains why the C# compiler won't let you declare another local variable in another scope block with the same name.

抖动大约有局部变量一生有趣的规则,他们完全被垃圾收集器是如何工作的主导。当它JITS的方法,它不只是产生该方法的机器代码,也创建描述每局部变量的实际范围,在那里它被初始化代码地址和在那里不再使用的代码的地址的表。垃圾收集器使用该表来决定是否对某个对象的引用是有效的,基于活动执行地址。

The jitter has interesting rules about local variable lifetime, they are entirely dominated by how the garbage collector works. When it jits a method, it doesn't just generate the machine code for the method but also creates a table that describes the actual scope of every local variable, the code address where it is initialized and the code address where it is no longer used. The garbage collector uses that table to decide if a reference to an object is valid, based on the active execution address.

这使得它的非常的高效的收集对象。有点太有时高效和麻烦,当你使用本地代码互操作,您可能需要魔法GC.KeepAlive()方法来延长寿命。非常了不起的方法,它不产生任何代码。其唯一用途是使抖动改变表,并插入了可变生命时间更大的地址

Which makes it very efficient at collecting objects. A little too efficient sometimes and troublesome when you interop with native code, you may need the magic GC.KeepAlive() method to extend the lifetime. A very remarkable method, it doesn't generate any code at all. Its only use is to get the jitter to change the table and insert a larger address for the variable life-time.

这篇关于明确本地作用域的 - 任何真正的好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆