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 the instruction that will be executed?

I will explain:

  • In Debug mode, the compiler does not optimize the code, so
    executable instruction is identical to the one described by myself
    programmer.
  • In Release mode, the same compiler inlineit, eliminates and in general
    changes many things so that the final executable instruction can
    seriously differ from what was originally described.

Does GetILAsByteArray() a compilation mode, or does this method always return a " verbatim " method instruction?

  • one
    Inline is not a C # compiler, but a JIT that converts IL to machine code. IL code lies in the assembly, and at the time of execution it does not change at all. - PashaPash
  • Understood, thanks) - Kir_Antipov
  • 2
    Those. it is not quite clear what you mean by "what the programmer described" and "the final executable instruction". The programmer writes in c #, the c # compiler converts the code into IL using optimizations. IL is bytes in the assembly. Then, on a particular platform, JIT converts IL into native code, applying its own optimizations. The method you are asking for returns IL. This is not "what the programmer wrote," and not "what will be really accomplished." This is an intermediate result in a portable intermediate language :) - PashaPash
  • @PashaPash Thank you, yet understood) For some reason I used to think that optimization is applied only at the stage of IL-code) Why not as an answer?) - Kir_Antipov
  • It is easier to make comments from the phone :) :( - PashaPash

1 answer 1

Does GetILAsByteArray () somehow compile mode

The answer is yes. This is easily seen in practice. Let's write a test method:

 public void Method(int a, int b) { string str = (a+b).ToString(); MessageBox.Show(str); } 

Next, we write the following code to extract the first operand from its MSIL code and display the operation name:

 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, at the beginning of each method, an empty statement is inserted to facilitate debugging (so that you can put a breakpoint at the very beginning of the method, whereas in the release build you can only on the first line). Thus, the compilation mode really affects the IL-code of the method.