I'm looking for a program that will show me the lowest level (ie. no syntactic sugar) C# code given IL code.
I tried using .NET Reflector to view a .exe file that contained a simple console app with a foreach
loop, hoping to see GetEnumerator()
, MoveNext()
, Current
etc, however it showed it as a foreach
loop.
Does such a program exist? Or is it possible to select "no syntactic sugar" in .NET Reflector?
On comment to YellowAfterlife OP said:
When iterating over an array it does not use an enumerator object. It uses an integer index counter variable instead. You know, like a for loop. The IL uses
OpCodes.Br_S
andOpCodes.Blt_S
, which we could say are "goto". Sure, you could write it as awhile
loop if you insist.For test, I wrote this code:
This is what ILSpy output:
In fact, in the IL, the check was moved after the loop, with a jump to it at the start. Please remember that
while
loop (unlike thedo ... while
loop) is supposed to check before. See the IL:Notice
ldlen
which gets the length of an array.You can verify this code on ShatpLab.
The compiler is optimizing access to the array. So, we could argue that the compiler turned my
while
loop in afor
loop.Current versions of ILSpy have a sizable set of options for enabling/disabling decompiler transformation features:
If needed, you could go further than this by stripping out logic in
ICSharpCode.Decompiler.IL.Transforms.*
andICSharpCode.Decompiler.CSharp.StatementBuilder
; Perhaps open an issue asking, whether a PR for your changes would be appreciated, as most of these "rawness" settings have been added relatively recently.A better example with enumerators
A laconic snippet of code
compiles to
(as seen with all transformation settings disabled)
Further on for-loops:
As far as compilation goes,
for (a; b; c) d
is the same asa; while (b) { d; c; }
(save for placement of continue-label), so decompilers will take liberty with deciding what kind of loop it might have been based on context similarity between init-statement, condition, and post-statement, so you might even write code by handthat will be detected as a for-loop (for there is no telling in IL)