Reputation: 21
For a simple Method with no local variables like the following
public static int Test1(short i, long j)
{
j = i + j;
switch (j)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}
return j;
}
The count of MethodInfo.GetMethodBody().LocalVariables.Count = 2 WHY? Add another switch statement and the count becomes 3 WHY?
public static int Test1(short i, long j)
{
j = i + j;
switch (j)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}
switch (i)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}
return j;
}
No local variables are defined. So why 2 and 3. Also if another switch statement with j keeps the count at 2.
Upvotes: 2
Views: 317
Reputation: 245038
The fact that C# compiler generates local variables that are not in your C# source code is to be expected, I think. That's because the IL stack is not always a great place to store some temporary values, because you can only access its top.
And this applies especially for debug builds, because those are optimized for debugging, not for performance or memory footprint. I have no idea how do those locals help the debugger, or whether they help at all, but I'm assuming they do have their point.
Specifically, your method actually won't compile, as jmh_gr pointed out, because you can't implicitly cast long
to int
. If I change the type of j
to int
, it produces code like this when using debug configuration (the decompiled by using Reflector, with optimizations disabled):
public static int Test1(short i, int j)
{
int CS$1$0000;
int CS$4$0001;
j = i + j;
CS$4$0001 = j;
if (CS$4$0001 != 1)
{
goto Label_0013;
}
j = 2;
goto Label_0019;
Label_0013:
j = 11;
Label_0019:
CS$1$0000 = j;
Label_001D:
return CS$1$0000;
}
So, you see, the method actually has two locals, and both are used. When using the release configurations, the generated IL has only one local variable and it looks like this:
public static int Test1(short i, int j)
{
int CS$0$0000;
j = i + j;
CS$0$0000 = j;
if (CS$0$0000 != 1)
{
goto Label_0010;
}
j = 2;
goto Label_0014;
Label_0010:
j = 11;
Label_0014:
return j;
}
It looks like the local shouldn't be necessary, but maybe there is a good reason for it. And of course, what really matters for performance is the JIT compiled assembly, not the IL code.
Upvotes: 2