ILSpy icon indicating copy to clipboard operation
ILSpy copied to clipboard

While instead of For statement

Open bprg opened this issue 6 years ago • 1 comments

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;
}

bprg avatar Jan 03 '19 13:01 bprg

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.

dgrunwald avatar Aug 08 '20 21:08 dgrunwald