Mono Cecil - 初始化局部变量

Dan*_*iel 2 c# mono.cecil

我有以下方法:

public void DoSomething()
{
  Console.WriteLine("");
}
Run Code Online (Sandbox Code Playgroud)

我想用 Mono Cecil 修改此代码。我想在方法中创建一个自定义类的实例:

public void DoSomething()
{
  MyClass instance = new MyClass();
  Console.WriteLine("");
}
Run Code Online (Sandbox Code Playgroud)

目前我使用以下代码:

  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);
  }
Run Code Online (Sandbox Code Playgroud)

应用这些更改后,程序无效且无法执行。如果我使用“IL DASM”查看生成的代码,则缺少以下语句:

.locals init ([0] class [MyAssembly]MyNamespace.MyClass instance)
Run Code Online (Sandbox Code Playgroud)

IL的其余部分是一样的,就好像我直接编译了完整代码一样。任何想法我做错了什么?

Alo*_*aus 5

我还没有尝试过,但是通过查看 Cecil 源代码,您应该首先创建作为MethodBody.

MethodBody有一个Variables可以通过填充的集合

body.Variables.Add( new VariableDefinition(typedef) )
Run Code Online (Sandbox Code Playgroud)

然后你需要打电话 processor.Create(xxx,indexto local variable);

这应该够了吧。我唯一还没有看到如何TypeDefinitionType. 我认为您需要先将程序集加载到 Mono Cecil 中,然后才能使用这种方法。