Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 语句块中的变量范围 for(int i=0;i_C#_Compiler Construction_Clr_Scope - Fatal编程技术网

C# 语句块中的变量范围 for(int i=0;i

C# 语句块中的变量范围 for(int i=0;i,c#,compiler-construction,clr,scope,C#,Compiler Construction,Clr,Scope,根据我对范围的理解,第一个例子应该很好。两人都不被允许的事实似乎更奇怪。当然,“我”要么在范围内,要么不在范围内 关于作用域是否有一些不明显的地方我不明白,这意味着编译器真的不能解决这个问题?还是仅仅是一个保姆国家编译主义的例子 或者只是一个保姆国家的例子 编译主义 正是这样。在同一个方法中“重用”变量名是没有意义的。在第一个示例中,在循环外声明i使i成为函数的局部变量。因此,在该函数的任何块中声明另一个变量名是错误的 第二,我只在循环期间在范围内。在循环之外,我不能再被访问 您已经看到了错误,

根据我对范围的理解,第一个例子应该很好。两人都不被允许的事实似乎更奇怪。当然,“我”要么在范围内,要么不在范围内

关于作用域是否有一些不明显的地方我不明白,这意味着编译器真的不能解决这个问题?还是仅仅是一个保姆国家编译主义的例子

或者只是一个保姆国家的例子 编译主义


正是这样。在同一个方法中“重用”变量名是没有意义的。在第一个示例中,在循环外声明i使i成为函数的局部变量。因此,在该函数的任何块中声明另一个变量名是错误的

第二,我只在循环期间在范围内。在循环之外,我不能再被访问

您已经看到了错误,但是这样做没有错

for (int i = 0; i < 10; i++)
{
    Foo();
}
int i = 10; // error, 'i' already exists

----------------------------------------    

for (int i = 0; i < 10; i++)
{
    Foo();
}
i = 10; // error, 'i' doesn't exist
for(int i=0;i<10;i++)
{
//做点什么
}
foreach(Foo-Foo-in-foos)
{
int i=42;
//做点什么
}

因为i的范围限制在每个块中。

这是因为声明空间在方法级别定义了
i
。变量
i
在循环结束时超出范围,但仍然无法重新声明
i
,因为该方法中已定义了
i

范围与声明空间:

你会想看看Eric Lippert的答案(默认情况下,他在这些问题上总是正确的)

以下是eric对上述帖子的评论,我认为这是关于他们为什么这么做的原因:

这样看。它应该总是 合法地提出申请 变量在源代码中出现的时间太长了 当你把它放在同一个街区, 正确的?如果我们像你那样做的话 建议,那么有时候就是这样 合法的,有时是非法的!但是 我们真正想避免的是 C++中发生的事情——C++中 有时移动一个变量 声明实际上改变了 其他简单名称的绑定


Me认为编译器的意思是说,
i
已在方法级别声明&范围在
for
循环中

因此,在案例1中,您会得到一个错误,即变量已经存在,它确实存在

&在情况2中-由于变量的作用域仅限于
for
循环内,因此无法在该循环外访问该变量

要避免这种情况,您可以:

for (int i = 0; i < 10; i++)
{
  // do something
}

foreach (Foo foo in foos)
{
   int i = 42;
   // do something 
}
var i=0;
对于(i=0,i<10,i++){
}
i=10;
但我想不出有哪种情况下你会想这么做

HTH

你需要做什么

var i = 0;

for(i = 0, i < 10, i++){
}

i = 10;
inti;
对于(i=0;i<10;i++)
{
}
i=10;
是的,我支持“保姆国家编译器”的评论。有趣的是这没关系

            int i ;
            for ( i = 0; i < 10; i++)
            {

            }
            i = 10;
for(int i=0;i<10;i++)
{
}
对于(int i=0;i<10;i++)
{
}
这没关系

for (int i = 0; i < 10; i++)
{

}

for (int i = 0; i < 10; i++)
{

}
for(int i=0;i<10;i++)
{
}
对于(int j=0;j<10;j++)
{
var i=12;
}
但事实并非如此

for (int i = 0; i < 10; i++)
{

}

for (int j = 0; j < 10; j++)
{
    var i = 12;                
}
for(int i=0;i<10;i++)
{
var x=2;
}
var x=5;
即使你能做到这一点

for (int i = 0; i < 10; i++)
{
    var x = 2;
}

var x = 5;
for(int i=0;i<10;i++)
{
var k=12;
}
对于(int i=0;i<10;i++)
{
var k=13;
}
这一切都有点不一致

编辑 基于下面与Eric的评论交流,我认为展示我如何处理循环可能会有所帮助。只要有可能,我会尝试将循环组合到它们自己的方法中。我这样做是因为它提高了可读性

之前

for (int i = 0; i < 10; i++)
{
    var k = 12;
}

for (int i = 0; i < 10; i++)
{
    var k = 13;
}
/*
*用同一个名字做两件不同的事情是不清楚的
*/
对于(var索引=0;索引
之后

/*
 * doing two different things with the same name is unclear
 */
for (var index = 0; index < people.Count; index++)
{
    people[index].Email = null;
}
var index = GetIndexForSomethingElse(); 
/*
*现在这个范围内的索引只有一个含义
*/
ClearEmailAddressesFor(人);//方法名现在的工作方式类似于注释
var index=GetIndexForSomethingElse();
/*
*现在索引在该方法的范围内只有一个含义。
*/
私有void ClearEmailAddressesFor(IList人员)
{
对于(var索引=0;索引
来自:

声明的局部变量的范围 在局部变量声明中 发生声明的块

当然,在声明之前不能使用
i
,但是
i
声明的范围是包含它的整个块:

/*
 * Now there is only one meaning for index in this scope
 */
ClearEmailAddressesFor(people); // the method name works like a comment now
var index = GetIndexForSomethingElse();

/*
 * Now index has a single meaning in the scope of this method.
 */
private void ClearEmailAddressesFor(IList<Person> people)
{
    for (var index = 0; index < people.Count; index++)
    {
        people[index].Email = null;
    }
}
根据我对范围的理解,第一个例子应该很好

你对范围的理解很好。这不是范围错误。这是一个使用简单名称不一致的错误

int i=10;//错误“i”已存在

这不是报告的错误。报告的错误是“无法在此范围内声明名为i的局部变量,因为它将赋予已在子范围内用于表示其他内容的i不同的含义”

错误消息告诉您错误是什么;请再次阅读错误消息。它没有说声明之间存在冲突;它说这个错误是因为它改变了简单名称的含义。错误是而不是重新声明;在两个不同的作用域中有两个具有相同名称的东西是完全合法的,即使这些作用域嵌套。不合法的是,在嵌套的局部变量声明空间中,一个简单的名称表示两种不同的东西

您将得到错误“一个名为i的局部变量已经在这个
{
    // scope starts here
    for (int i = 0; i < 10; i++)
    {
        Foo();
    }
    int i = 10;
}
{
    int i = 10;

    // collision with i
    for (int i = 0; i < 10; i++)
    {
        Foo();
    }
}
int i = 10;
int i = 10;
class C 
{
    int i;
    void M()
    {
        string i;
class C 
{
    int i;
    void M()
    {
        int x = i;
        foreach(char i in ...
class Test
{
    int i;
    static int si=9; 

    public Test()
    {
        i = 199;
    }

    static void main()
    {
        for (int i = 0; i < 10; i++)
        {
            var x = 2;
        }

        { var x = 3; }

        {    // remove outer "{ }" will generate compile error
            int si = 3; int i = 0;

             Console.WriteLine(si);
             Console.WriteLine(Test.si);
             Console.WriteLine(i);
             Console.WriteLine((new Test()).i);
        }
    }
}