ILSpy
ILSpy copied to clipboard
While instead of For statement
IL
.method private hidebysig static
bool MyMethod (
class [mscorlib]System.Reflection.MethodBase method
) cil managed
{
// Method begins at RVA 0xf9e8
// Code size 44 (0x2c)
.maxstack 2
.locals init (
[0] class [mscorlib]System.Reflection.ParameterInfo[],
[1] int32
)
IL_0000: ldarg.0
IL_0001: callvirt instance class [mscorlib]System.Reflection.ParameterInfo[] [mscorlib]System.Reflection.MethodBase::GetParameters()
IL_0006: stloc.0
IL_0007: ldc.i4.0
IL_0008: stloc.1
IL_0009: br.s IL_0022
// loop start (head: IL_0022)
IL_000b: ldloc.0
IL_000c: ldloc.1
IL_000d: ldelem [mscorlib]System.Reflection.ParameterInfo
IL_0012: callvirt instance class [mscorlib]System.Type [mscorlib]System.Reflection.ParameterInfo::get_ParameterType()
IL_0017: callvirt instance bool [mscorlib]System.Type::get_IsByRef()
IL_001c: brtrue.s IL_002a
IL_001e: ldloc.1
IL_001f: ldc.i4.1
IL_0020: add
IL_0021: stloc.1
IL_0022: ldloc.1
IL_0023: ldloc.0
IL_0024: ldlen
IL_0025: conv.i4
IL_0026: blt.s IL_000b
// end loop
IL_0028: ldc.i4.0
IL_0029: ret
IL_002a: ldc.i4.1
IL_002b: ret
ILSpy
private static bool MyMethod(MethodBase method)
{
ParameterInfo[] parameters = method.GetParameters();
int num = 0;
while (true)
{
if (num < parameters.Length)
{
if (parameters[num].ParameterType.IsByRef)
{
break;
}
num++;
continue;
}
return false;
}
return true;
}
Other Decompiler
private static bool MyMethod(MethodBase method)
{
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i].ParameterType.IsByRef)
{
return true;
}
}
return false;
}
The issue here is that ILSpy assumes the order of the IL blocks is indicative of the order of the C# code. This usually works well for assemblies compiled by the C# compiler.
In the IL the return true;
is clearly after the return false;
, so ILSpy tries to arrange the C# code in the same way.
Given our approach to loop detection, I don't see anything we could improve here without breaking a lot of other cases.