Question:
Method MethodBody.GetILAsByteArray();
returns IL code in byte representation, this is clear. However, I did not find specifics in the description of the operation of this method on MSDN
: does it return the " verbatim " instruction that I described, or does this function return exactly the instruction that will be executed?
Let me explain:
- In Debug mode, the compiler does not optimize the code in any way, so
the executable instruction is identical to the one that he himself described
programmer. - In Release mode, the compiler inline, abolishes and generally
changes many things so that the final executable instruction can
seriously different from what was originally described.
Is GetILAsByteArray()
somehow affected by compilation mode, or does this method always return a " verbatim " method statement?
Answer:
Does the compilation mode somehow affect GetILAsByteArray()
The answer is yes. This is easy to verify in practice. Let's write a test method:
public void Method(int a, int b)
{
string str = (a+b).ToString();
MessageBox.Show(str);
}
Next, write the following code to extract the first operand from its MSIL code and display the name of the operation:
using System;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
...
var mi = this.GetType().GetMethod("Method");
byte[] msil = mi.GetMethodBody().GetILAsByteArray();
ushort op;
if(msil[0]==0xfe)
op = (ushort)(msil[1] | 0xfe00);
else
op = (ushort)(msil[0]);
//найдем имя операции
string str="";
FieldInfo[] mas = typeof(OpCodes).GetFields();
for(int i=0;i<mas.Length;i++)
{
if (mas[i].FieldType == typeof(OpCode))
{
OpCode opcode = (OpCode)mas[i].GetValue(null);
if (opcode.Value == op)
{
str = opcode.ToString();
break;
}
}
}
textBox1.Text = "0x"+op.ToString("X4")+": "+str;
Result:
Debug – 0x0000: nop
Release- 0x0003: ldarg.1
This is explained by the fact that in the debug build, an empty statement is inserted at the beginning of each method to facilitate debugging (so that you can put a breakpoint at the very beginning of the method, while in the release build you can only on the first line). So the compilation mode does affect the IL code of the method.