この C# コード:
private void LoadAssignments(AssignmentType assignmentType, Collection<Assignment> assignments)
{
bool flag;
DataTable lessons = this.GetResults(assignmentType);
try
{
IEnumerator enumerator = lessons.Rows.GetEnumerator();
try
{
while (true)
{
flag = enumerator.MoveNext();
if (!flag)
{
break;
}
DataRow row = (DataRow)enumerator.Current;
}
}
finally
{
IDisposable disposable = enumerator as IDisposable;
flag = disposable == null;
if (!flag)
{
disposable.Dispose();
}
}
}
finally
{
flag = lessons == null;
if (!flag)
{
lessons.Dispose();
}
}
}
この CIL を生成します (.NET 4)
.method private hidebysig
instance void LoadAssignments (
valuetype TTReporterCore.AssignmentType assignmentType,
class [mscorlib]System.Collections.ObjectModel.Collection`1<valuetype TTReporterCore.Assignment> assignments
) cil managed
{
.locals init (
[0] bool flag,
[1] class [System.Data]System.Data.DataTable lessons,
[2] class [mscorlib]System.Collections.IEnumerator enumerator,
[3] class [System.Data]System.Data.DataRow row,
[4] class [mscorlib]System.IDisposable disposable,
[5] bool flag1
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance class [System.Data]System.Data.DataTable TTReporterCore.TTReader::GetResults(valuetype TTReporterCore.AssignmentType)
IL_0008: stloc.1
.try
{
IL_0009: nop
IL_000a: ldloc.1
IL_000b: callvirt instance class [System.Data]System.Data.DataRowCollection [System.Data]System.Data.DataTable::get_Rows()
IL_0010: callvirt instance class [mscorlib]System.Collections.IEnumerator [System.Data]System.Data.InternalDataCollectionBase::GetEnumerator()
IL_0015: stloc.2
.try
{
IL_0016: nop
IL_0017: br.s IL_0038
.loop
{
IL_0019: nop
IL_001a: ldloc.2
IL_001b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
IL_0020: stloc.0
IL_0021: ldloc.0
IL_0022: stloc.s flag1
IL_0024: ldloc.s flag1
IL_0026: brtrue.s IL_002b
IL_0028: nop
IL_0029: br.s IL_003d
IL_002b: ldloc.2
IL_002c: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current()
IL_0031: castclass [System.Data]System.Data.DataRow
IL_0036: stloc.3
IL_0037: nop
IL_0038: ldc.i4.1
IL_0039: stloc.s flag1
IL_003b: br.s IL_0019
}
IL_003d: nop
IL_003e: leave.s IL_0062
}
finally
{
IL_0040: nop
IL_0041: ldloc.2
IL_0042: isinst [mscorlib]System.IDisposable
IL_0047: stloc.s disposable
IL_0049: ldloc.s disposable
IL_004b: ldnull
IL_004c: ceq
IL_004e: stloc.0
IL_004f: ldloc.0
IL_0050: stloc.s flag1
IL_0052: ldloc.s flag1
IL_0054: brtrue.s IL_0060
IL_0056: nop
IL_0057: ldloc.s disposable
IL_0059: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_005e: nop
IL_005f: nop
IL_0060: nop
IL_0061: endfinally
}
IL_0062: nop
IL_0063: nop
IL_0064: leave.s IL_007e
}
finally
{
IL_0066: nop
IL_0067: ldloc.1
IL_0068: ldnull
IL_0069: ceq
IL_006b: stloc.0
IL_006c: ldloc.0
IL_006d: stloc.s flag1
IL_006f: ldloc.s flag1
IL_0071: brtrue.s IL_007c
IL_0073: nop
IL_0074: ldloc.1
IL_0075: callvirt instance void [System]System.ComponentModel.MarshalByValueComponent::Dispose()
IL_007a: nop
IL_007b: nop
IL_007c: nop
IL_007d: endfinally
}
IL_007e: nop
IL_007f: ret
}
MSIL が flag1 を追加し、同じロジックを実行してフラグを設定し、flag1 をフラグに設定し、最後に !flag1 をチェックするのはなぜですか。これは、コンパイラの非効率性のように思えます。
更新: Telerik の JustDecompile を使用していましたが、結果は ILDASM とはかなり異なりますが、追加のブール値はデバッグ モードで作成されます。
また、ブール値を完全に削除してコードを変更しましたが、デバッグ バージョンでもブール値が追加されます。コンパイラがこれを行う理由を本当に探しています。