在C#中的变量范围混乱 [英] Variable scope confusion in C#

查看:156
本文介绍了在C#中的变量范围混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个code样品。先不编译,但第二个呢。

I have two code samples. The first does not compile, but the second does.

code样品1 (不编译)

public void MyMethod(){
    int i=10;

    for(int x=10; x<10; x++) {
        int i=10; // Point1: compiler reports error
        var objX = new MyOtherClass();
    }

    var objX = new OtherClassOfMine(); // Point2: compiler reports error
}

我明白为什么编译器在点1 报告错误。但我不明白为什么它在报告点2 错误。如果你说这是因为里面MSIL组织的,那为什么第二个code编译例子?

I understand why the compiler reports an error at Point1. But I don't understand why it reports an error at Point2. And if you say it is because of the organization inside MSIL, then why does the second code example compile?

code样品2 (编译)

public void MyMethod(){

    for(int x=10; x<10; x++) {
        int i=10; 
        var objX = new MyOtherClass();
    }

    for(int x=10; x<10; x++) {
        int i=10; 
        var objX = new MyOtherClass();
    }
}

如果变量范围的简单规则,code示例2适用,那么为什么不这些规则同样适用于code样品1?

If the simple rules of variable scope apply in Code Sample 2, then why don't those same rules apply to Code Sample 1?

推荐答案

这里有两个相关的规则。

There are two relevant rules here.

第一个相关的规则是:

它是一个局部变量的误差
  声明空间和嵌套的地方
  变量声明空间包含
  元素具有相同的名称。

It is an error for a local variable declaration space and a nested local variable declaration space to contain elements with the same name.

(而这个页面上的另一个答案召唤出在这里我们再次调用此出规范的其他位置。)

(And another answer on this page calls out another location in the specification where we call this out again.)

这本身就足以让这个非法的,但实际上第二个规则使这种非法。

That alone is enough to make this illegal, but in fact a second rule makes this illegal.

在C#中的第二个相关的规则是:

The second relevant rule in C# is:

有关的给定的每次出现
  标识符作为在一个简单名称
  前pression或声明符,内
  局部变量声明空间,
  立即封闭块,或
  开关块发生,
  相同的每次其它出现时
  标识符作为在一个简单名称
  中前pression或声明符
  立即封闭块或
  开关块必须是指同一
  实体。此规则确保
  一个名称的含义是总是相同
  一个给定的块中,切换块,
  用户资格,foreach-或使用语句,或
  匿名函数。

For each occurrence of a given identifier as a simple-name in an expression or declarator, within the local variable declaration space, immediately enclosing block, or switch-block of that occurrence, every other occurrence of the same identifier as a simple-name in an expression or declarator within the immediately enclosing block or switch-block must refer to the same entity. This rule ensures that the meaning of a name is always the same within a given block, switch block, for-, foreach- or using-statement, or anonymous function.

您还需要知道,因为虽然有隐形牙套围绕整个事情for循环处理。

You also need to know that a for-loop is treated as though there are "invisible braces" around the whole thing.

现在我们知道,让我们来注解你的code:

Now that we know that, let's annotate your code:

public void MyMethod()
{ // 1
    int i=10; // i1
    { // 2 -- invisible brace
      for(int x=10; x<10; x++) // x2
      { // 3
        int i=10;  // i3
        var objX = new MyOtherClass(); // objX3
      } // 3
    } // 2
    var objX = new OtherClasOfMine(); // objX1
} // 1

您有三个简单名称,I,X和物objx。你有五个变量,我已经标记为I​​1,X2,I3,objX3和objX1。

You have three "simple names", i, x and objX. You have five variables, which I've labeled i1, x2, i3, objX3, and objX1.

这包含用法我和物objx是块1。因此,块1中的最外层块,我和物objx必须始终指的是同样的事情。但他们没有。有时我指的是I1,有时它指的是酷睿i3。同样的,物objx。

The outermost block that contains usages of i and objX is block 1. Therefore, within block 1, i and objX must always refer to the same thing. But they do not. Sometimes i refers to i1 and sometimes it refers to i3. Same with objX.

X,然而,只有永远意味着X2,在每一个块中。

x, however, only ever means x2, in every block.

另外,两个I变量都在同一个局部变量声明空间,因为都是物objx变量。

Also, both "i" variables are in the same local variable declaration space, as are both "objX" variables.

因此​​,这个计划是一个错误在几个方面。

Therefore, this program is an error in several ways.

在你的第二个程序:

public void MyMethod()
{ // 1
    { // 2 -- invisible 
      for(int x=10; x<10; x++)   // x2
      { // 3
        int i=10;  // i3
        var objX = new MyOtherClass(); // objX3
      } //3 
    } // 2
    { // 4 -- invisible
      for(int x=10; x<10; x++)  // x4
      { // 5
        int i=10;  // i5
        var objX = new MyOtherClass();  // objX5
      } //5
   } // 4
} // 1

现在你又有三个简单的名称和六个变量。

Now you have three simple names again, and six variables.

这是第一个包含简单的名称x的使用最外面的块是块2和4,在整个块2,x表示X2。纵观块4,X指的是X4。因此,这是合法的。同样与i和物objx - 它们在块3和5使用,指在每个不同的事情。但无处是用于在整个同一块意味着两个不同的东西一样简单的名称。

The outermost blocks that first contain a usage of simple name x are blocks 2 and 4. Throughout block 2, x refers to x2. Throughout block 4, x refers to x4. Therefore, this is legal. Same with i and objX -- they are used in blocks 3 and 5 and mean different things in each. But nowhere is the same simple name used to mean two different things throughout the same block.

现在,你可能会注意到,考虑所有块1 的,x被用于指x2和x4。但是,没有任何的x提到,里面是块1,但不也是另外一个块中。因此,我们不指望在块1不一致的用法有关。

Now, you might note that considering all of block 1, x is used to mean both x2 and x4. But there's no mention of x that is inside block 1 but NOT also inside another block. Therefore we don't count the inconsistent usage in block 1 as relevant.

此外,没有任何的声明空间非法方式重叠。

Also, none of the declaration spaces overlap in illegal ways.

因此​​,这是合法的。

Therefore, this is legal.

这篇关于在C#中的变量范围混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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