使用Mono.Cecil将实例字段添加到类中

时间:2018-08-02 22:43:54

标签: c# mono.cecil

我最近开始研究Mono.Cecil。我有一个问题,对于使用此库的人来说,我很确定这很简单。

我想做什么:

  1. 将给定类型的私有字段添加到Class1
  2. 在Class1构造函数中初始化此字段(尚未到达这里:))

我的代码是:

public class Tools
{
    public void AddField(string fileName)
    {
        using (ModuleDefinition module = ModuleDefinition.ReadModule(fileName, new ReaderParameters { ReadWrite = true }))
        {
            TypeDefinition[] types = module.Types.ToArray();
            foreach (var type in types)
            {
                if (type.Name == "Class2")
                {
                    continue;
                }
                type.Fields.Add(new FieldDefinition("addedField", Mono.Cecil.FieldAttributes.Private, module.ImportReference(typeof(Int32))));
            }
            module.Write(); // Write to the same file that was used to open the file
        }
    }
}

完成后,这就是我在ILSpy中看到的内容:

.class public auto ansi beforefieldinit ClassLibrary3.Class1
    extends [mscorlib]System.Object
{
    // Fields
    .field private int32 testint
    .field private int32 addedField

    // Methods
...
在使用Mono.Cecil处理库之前,我直接在C#中添加了

testInt。它与Mono.Cecil为addedField生成的内容相同。但是,当我尝试使用控制台应用程序加载此修改后的程序集时,它抛出TypeLoadException:非静态全局字段。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

一段时间后我找到解决方案时,我会回答自己,也许有人会觉得有用。这是引起我痛苦的部分:

if (type.Name == "Class2")
{
continue;
}

阅读这篇文章后: What is the "<Module>" type?我意识到实际上我在<Module>类型中添加了一些字段,这给我带来了麻烦。更改我的逻辑以将新字段添加到指定的类之后,它才按预期工作。