Question

I have the following method:

public void DoSomething()
{
  Console.WriteLine("");
}

I want to modify this code with Mono Cecil. I want to create an instance of a custom class within the method:

public void DoSomething()
{
  MyClass instance = new MyClass();
  Console.WriteLine("");
}

Currently I use the following code:

  var constructorInfo = typeof(MyClass).GetConstructor(new Type[] { });
  MethodReference myClassConstructor = targetAssembly.MainModule.Import(constructorInfo);

  var processor = targetMethod.Body.GetILProcessor();
  var firstInstruction = targetMethod.Body.Instructions[1];

  var instructions = new List<Instruction>() {
      processor.Create(OpCodes.Newobj, myClassConstructor),
      processor.Create(OpCodes.Stloc_0)
  };

  foreach (var instruction in instructions)
  {
      processor.InsertBefore(firstInstruction, instruction);
  }

After applying those changes, the program is invalid and cannot be executed. If i use 'IL DASM' to look at the generated code the following statement is missing:

.locals init ([0] class [MyAssembly]MyNamespace.MyClass instance)

The rest of the IL is the same, as if I directly compile the full code. Any ideas what I am doing wrong?

Was it helpful?

Solution

I have not tried it but by looking at the Cecil Source Code you should first create the local variable which is part of your MethodBody.

MethodBody has a Variables collection which can be filled via

body.Variables.Add( new VariableDefinition(typedef) )

Then you need to call processor.Create(xxx,indexto local variable);

That should do the trick. The only thing I did not see yet how you can get a TypeDefinition out from a Type. I think you need to load the assembly into Mono Cecil first before you can use this approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top