What are these opcodes for?
Question
Using reflector I get the following output:
.method private hidebysig static class myModelTestarea.Foo Method() cil managed
{
.maxstack 1
.locals init ([0] class myModelTestarea.Foo CS$1$0000)
L_0000: nop
L_0001: ldc.i4.0
L_0002: newarr object
L_0007: call object myModelTestarea.Program::Resolve(object[])
L_000c: castclass myModelTestarea.Foo
L_0011: stloc.0
L_0012: br.s L_0014
L_0014: ldloc.0
L_0015: ret
}
for
private static Foo Method()
{
return (Foo)Resolve();
}
private static object Resolve( params object[] args )
{
return new Foo();
}
What do the lines 11-14 do? I call a function and get a result (line 7). I cast the result to the right returntype (line c) - why not return right now?
Somehow, the casted result is stored as a local variable - then there is an uncoditional jump to the next line, where the local variable is loaded again. Why?
In my opinion line 11-14 and the local variable can be omitted ... ?
Solution
That looks like a DEBUG build, which leaves in extra IL to help the debugger. Try it again in RELEASE and it should look cleaner, with optimization etc.
.method private hidebysig static class program/Foo Method() cil managed
{
.maxstack 8
L_0000: ldc.i4.0
L_0001: newarr object
L_0006: call object program::Resolve(object[])
L_000b: castclass program/Foo
L_0010: ret
}
OTHER TIPS
Is this a debug build? It's possible that it's there for the sake of the debugger.
I've seen similar things in other places - it's almost always harmless though. Don't forget that most of the optimisation is done by the JIT, which can notice things like this easily enough. The only downside is that more IL hints to the JIT that the method shouldn't be inlined.