将静态实例字段添加到类并在构造函数中设置为自身

问题描述

使用 Mono.Cecil 我试图修补一个类以添加一个静态字段“Instance”并将其设置在构造函数中。它本质上相当于添加以下内容

public static Class1 Instance;
public Class1() {
    // does normal constructor stuff
    Class1.Instance = this;
}

不过,我不知道引用存在于何处,并且在查看 OpCodes 后,我找不到如何将引用推送到堆栈上以将字段 (OpCodes.Stfld) 存储到我的字段定义中。

不过,这是我目前所拥有的。

public static void Patch(AssemblyDeFinition assembly) {
    TypeDeFinition wfcDeFinition = assembly.MainModule.Types.First(t => t.Name == "WinFormConnection");
    MethodDeFinition wfcConstructor = wfcDeFinition.GetConstructors().First(t => t.IsConstructor);

    FieldDeFinition instField = new FieldDeFinition("Instance",FieldAttributes.Public | FieldAttributes.Static,wfcConstructor.DeclaringType);
    wfcDeFinition.Fields.Add(instField);

    ILProcessor proc = wfcConstructor.Body.GetILProcessor();

    // Where does the instance exist within the stack?
    // Instruction pushInstance = proc.Create(OpCodes.?);
    Instruction alLocinstance = proc.Create(OpCodes.Stfld,instField);

    // proc.Body.Instructions.Add(pushInstance);
    proc.Body.Instructions.Add(alLocinstance);
}

解决方法

this 始终是该方法的第一个参数,即,您需要执行以下操作:

...
  Instruction pushInstance = proc.Create(OpCodes.Ldarg_0);
  proc.Body.Instructions.Add(pushInstance);

  Instruction store = proc.Create(OpCodes.Stsfld,instField);
  proc.Body.Instructions.Add(store);

还要注意,您需要使用 Stsfld(存储静态字段)而不是 Stfld(存储实例字段)