浏览:276 2008-05-25 16:17 来自 A.feng..      :

代码一:
int i;
for (i = 0; i < 3; i++)
{
}
Console.WriteLine(i); // 正常

代码二:
for (int i = 0; i < 3; i++)
{
}
// Console.WriteLine(i); 变量i超出作用范围

上面两段代码生成的IL代码如下:
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       20 (0x14)
  .maxstack  2
  .locals init ([0] int32 i,
           [1] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  br.s       IL_000b
  IL_0005:  nop
  IL_0006:  nop
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.1
  IL_0009:  add
  IL_000a:  stloc.0
  IL_000b:  ldloc.0
  IL_000c:  ldc.i4.3
  IL_000d:  clt
  IL_000f:  stloc.1
  IL_0010:  ldloc.1
  IL_0011:  brtrue.s   IL_0005
  IL_0013:  ret
} // end of method Program::Main

因为生成的IL代码是一模一样的,所以只贴出完整的一段,不能理解的是在这样一段相同的IL代码中,CLR究竟是如何确定变量i的作用域的呢?请教大家了:)

 

收藏 楼主
  4个月前  玉开      :
mark,期待高人详解。
1楼 回到顶楼 
  4个月前 【组长】 Anytao      :
第二段代码是编译通不过的,猜测不错的话,两次Reflect的同一程序集,所以肯定没有区别,从这个层面分析是没有结果的。

IL中for循环的实现是通过br.s、brtrue指令来实现的,你的反编译代码已经很好的说明了这个问题,详细的情况可以参考该指令来了解。
2楼 回到顶楼 
  4个月前  红泥      :
变量的作用域是编译器来检查的,IL中所有局部变量的作用范围都是整个方法(不同的局部变量有不同的名字,不存在名称冲突)。
希望没说错
3楼 回到顶楼 
  2个月前  Colin Han      :
楼上的正解。
如果你在其中有一个匿名函数,问题才会复杂化。同样,你通过IL也可以看出来了。
4楼 回到顶楼 

注册用户登录后才能回复,登录注册
> 返回“CLR基础研究小组”


其他话题

相关内容

相关链接

1 32696