I have the following C# code:
public static double f(double x1, double x2 = 1)
{
return x1 * x2;
}
And here it's IL code (ILSpy):
.method public hidebysig static
float64 f (
float64 x1,
[opt] float64 x2
) cil managed
{
.param [2] = float64(1)
// Method begins at RVA 0x20c6
// Code size 4 (0x4)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: mul
IL_0003: ret
} // end of method A::f
How can I get it with System.Reflection.Emit or better with the Mono.Cecil?
If I want to do stuff with Mono.Cecil
I usually create a class / method in C#
with the expected code. I then inspect it (Make sure you're running it in Release mode) with Mono.Cecil
and re-create it.
So you'd need a MethodDefinition
with a name
, attributes
and returnType
parameter.
The name: "f"
The attributes for your method would be : Mono.Cecil.MethodAttributes.FamANDAssem | Mono.Cecil.MethodAttributes.Family | Mono.Cecil.MethodAttributes.Static | Mono.Cecil.MethodAttributes.HideBySig
And the return type (of type Mono.Cecil.TypeReference
as System.Double
)
As for the parameters, there are two ParameterDefinition
you can add with target.Parameters.Add()
One of your parameters has a default value so its attributes must be Mono.Cecil.ParameterAttributes.Optional | Mono.Cecil.ParameterAttributes.HasDefault
and its Constant
set to 1.0
(In your case)
Now for the method body:
target.Body.GetILProcessor(); // target is your `MethodDefinition` object.
After inspecting the instructions from target.Body.Instructions
, we see the following codes :
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: mul
IL_0003: stloc.0
IL_0004: br.s IL_0007
IL_0005: ldloc.0
IL_0007: ret
So just add the codes in the right sequence
processor.Append(OpCodes.Ldarg_0);
After that, inject / save your MethodDefinition
to the respective assembly.
My assembly inspector code looks something like this:
private static void EnumerateAssembly(AssemblyDefinition assembly)
{
foreach (var module in assembly.Modules)
{
foreach (var type in module.GetAllTypes())
{
foreach (var field in type.Fields)
{
Debug.Print(field.ToString());
}
foreach (var method in type.Methods)
{
Debug.Print(method.ToString());
foreach (var instruction in method.Body.Instructions)
{
Debug.Print(instruction.ToString());
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With