try / catchを持つためとのtry / catchせずに、すべての統計情報を見た後、好奇心を見て私を強制的に後ろの両方のケースのために生成されるかを確認します。これがコードです:
C#:
private static void TestWithoutTryCatch(){
Console.WriteLine("SIN(1) = {0} - No Try/Catch", Math.Sin(1));
}
MSIL:
.method private hidebysig static void TestWithoutTryCatch() cil managed
{
// Code size 32 (0x20)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "SIN(1) = {0} - No Try/Catch"
IL_0006: ldc.r8 1.
IL_000f: call float64 [mscorlib]System.Math::Sin(float64)
IL_0014: box [mscorlib]System.Double
IL_0019: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_001e: nop
IL_001f: ret
} // end of method Program::TestWithoutTryCatch
C#:
private static void TestWithTryCatch(){
try{
Console.WriteLine("SIN(1) = {0}", Math.Sin(1));
}
catch (Exception ex){
Console.WriteLine(ex);
}
}
MSIL:
.method private hidebysig static void TestWithTryCatch() cil managed
{
// Code size 49 (0x31)
.maxstack 2
.locals init ([0] class [mscorlib]System.Exception ex)
IL_0000: nop
.try
{
IL_0001: nop
IL_0002: ldstr "SIN(1) = {0}"
IL_0007: ldc.r8 1.
IL_0010: call float64 [mscorlib]System.Math::Sin(float64)
IL_0015: box [mscorlib]System.Double
IL_001a: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_001f: nop
IL_0020: nop
IL_0021: leave.s IL_002f //JUMP IF NO EXCEPTION
} // end .try
catch [mscorlib]System.Exception
{
IL_0023: stloc.0
IL_0024: nop
IL_0025: ldloc.0
IL_0026: call void [mscorlib]System.Console::WriteLine(object)
IL_002b: nop
IL_002c: nop
IL_002d: leave.s IL_002f
} // end handler
IL_002f: nop
IL_0030: ret
} // end of method Program::TestWithTryCatch
私はILの専門家ではありませんが、ローカル例外オブジェクトが4行目に作成され、.locals init ([0] class [mscorlib]System.Exception ex)
その後17行目まではtry / catchを使用しないメソッドの場合とほぼ同じIL_0021: leave.s IL_002f
です。例外が発生すると、コントロールは行IL_0025: ldloc.0
にジャンプしIL_002d: leave.s IL_002f
ます。それ以外の場合は、ラベルにジャンプし、関数が戻ります。
例外が発生しない場合は、例外オブジェクトとジャンプ命令のみを保持するのがローカル変数の作成のオーバーヘッドであると、私は安全に想定できます。