Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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循环的使用_C# - Fatal编程技术网

C# 未签名变量for循环的使用

C# 未签名变量for循环的使用,c#,C#,我有一个关于为for循环中的变量赋值的问题。据我所知,如Microsoft所述,当变量尚未赋值时可能被读取时,编译器会给出此错误消息 请注意,此错误是在编译器遇到可能导致使用未赋值变量的构造时生成的,即使您的特定代码没有 我的代码如下所示: static void Main(string[] args) { int i; for (int j = 0; j <= 5; j++) { i = j; } Console.WriteLi

我有一个关于为
for
循环中的变量赋值的问题。据我所知,如Microsoft所述,当变量尚未赋值时可能被读取时,编译器会给出此错误消息

请注意,此错误是在编译器遇到可能导致使用未赋值变量的构造时生成的,即使您的特定代码没有

我的代码如下所示:

static void Main(string[] args)
{
    int i;

    for (int j = 0; j <= 5; j++)
    {
        i = j;
    }

    Console.WriteLine(i.ToString());

    Console.ReadLine();
}
int i;

for (int j = 0; j <= GetUpperLimit(); j++)
{
    i = j;
}

同样的?

因为您在for循环中为变量
i
赋值,所以编译器不够聪明,无法看到是否会给它赋值,因此会出现错误

一个简单的解决方案是为变量指定一些默认值

int i = 0;
尽管从循环变量值来看,控件似乎将为循环输入
,但编译器无法确定这一点

错误的原因是因为语言规范

在函数成员的可执行代码中的给定位置 如果编译器能够证明, 通过静态流分析,表明变量已自动初始化或已成为至少一个赋值的目标


评估条件不是静态流,它将在运行时确定。因此,编译器无法确定是否将
i
赋值

您当前的案例似乎微不足道,但如果您的循环如下所示:

static void Main(string[] args)
{
    int i;

    for (int j = 0; j <= 5; j++)
    {
        i = j;
    }

    Console.WriteLine(i.ToString());

    Console.ReadLine();
}
int i;

for (int j = 0; j <= GetUpperLimit(); j++)
{
    i = j;
}
结果IL:

IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_000D
IL_0005:  nop         
IL_0006:  ldloc.1     // j
IL_0007:  stloc.0     // i
IL_0008:  nop         
IL_0009:  ldloc.1     // j
IL_000A:  ldc.i4.1    
IL_000B:  add         
IL_000C:  stloc.1     // j
IL_000D:  ldloc.1     // j
IL_000E:  ldc.i4.m1   
IL_000F:  cgt         
IL_0011:  ldc.i4.0    
IL_0012:  ceq         
IL_0014:  stloc.2     // CS$4$0000
IL_0015:  ldloc.2     // CS$4$0000
IL_0016:  brtrue.s    IL_0005
IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_0005
IL_0005:  ldc.i4.0    
IL_0006:  stloc.2     // CS$4$0000
现在使用一个错误的文本而不是表达式:

int i;

for (int j = 0; false; j++)
{
    i = j;
}
结果IL:

IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_000D
IL_0005:  nop         
IL_0006:  ldloc.1     // j
IL_0007:  stloc.0     // i
IL_0008:  nop         
IL_0009:  ldloc.1     // j
IL_000A:  ldc.i4.1    
IL_000B:  add         
IL_000C:  stloc.1     // j
IL_000D:  ldloc.1     // j
IL_000E:  ldc.i4.m1   
IL_000F:  cgt         
IL_0011:  ldc.i4.0    
IL_0012:  ceq         
IL_0014:  stloc.2     // CS$4$0000
IL_0015:  ldloc.2     // CS$4$0000
IL_0016:  brtrue.s    IL_0005
IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_0005
IL_0005:  ldc.i4.0    
IL_0006:  stloc.2     // CS$4$0000

类似地,
if(false){…}
进行了优化,但没有
bool b=false;如果(b){…}
。这是静态分析的结果。

只是作为一个旁白,这是因为编译器在评估变量是否初始化时不考虑嵌套的范围,所以这是一个更一般的问题。@马格斯:我认为我不能把一个评论标记为一个被接受的答案,但是如果我可以的话,我会。我想知道它的总体外观。@Magus,你所说的嵌套作用域是什么意思,我想这是因为条件。如果您有像
{{{i=10;}}}
这样的变量赋值,而不是
for
循环,则不会出现任何错误。这个错误是因为编译器不能计算条件,很明显我错了。但是,它确实扩展到了某些上下文,例如
try
if
,但不是使用
块的
。@Kapol,原因不是嵌套的作用域,而是C#specs中指定的静态流分析。在您的示例中,编译器事先不知道这一点,这是对的,但在我的示例中,它会知道。因此出现了轻微的混乱。