我有以下代码
using System;
class Pankaj
{
public static int Main()
{
int returnValue=0;
try
{
return returnValue;
throw new Exception();
}
catch(Exception ex){
return returnValue;
}
finally
{
returnValue++;
}
return returnValue;
}
}
Run Code Online (Sandbox Code Playgroud)
上面代码生成的MSIL是:
.method public hidebysig static int32 Main() cil managed
{
.entrypoint
// Code size 18 (0x12)
.maxstack 2
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldc.i4.0
IL_0001: stloc.0
.try
{
.try
{
IL_0002: ldloc.0
IL_0003: stloc.1
IL_0004: leave.s IL_0010
} // end .try
catch [mscorlib]System.Exception
{
IL_0006: pop
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: leave.s IL_0010
} // end handler
} // end .try
finally
{
IL_000b: ldloc.0
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: stloc.0
IL_000f: endfinally
} // end handler
IL_0010: ldloc.1
IL_0011: ret
} // end of method Pankaj::Main
Run Code Online (Sandbox Code Playgroud)
我有以下问题:
Jon*_*eet 11
为什么try catch再次包含在try块中.
在这一点上不确定.它可能只是ildasm选择反编译的方式.ECMA-335表示SEHClause在a之后如何指定元素有限制TryBlock,但我还没有找到这些限制.
它看起来像leave.sp和catch块的最后一行是指向最后即IL_0010但是在行IL_0010它的ldloc.1我认为这意味着在堆栈上加载局部变量1,然后它指向finally块.它是在位置1,我们有finally块的地址.
不,那是跳跃后的finally块-返回值,有效.你有很多返回语句都返回相同的东西,以及无法访问的代码,这没有帮助,但我相信这一点基本上只是移动到ret外面的try和catch.我认为编译器正在为返回值有效地设置一个额外的局部变量.
如果我从catch块中抛出或返回一些内容,那么调用语句如何落到finally块中,它已经从catch块返回但仍然执行finally块.
这就是C#和IL的定义方式 - 无论你退出finally块,都会执行块.
| 归档时间: |
|
| 查看次数: |
1543 次 |
| 最近记录: |