2

I've recently started to explore Mono.Cecil. I have one issue which I'm quite sure is very simple for someone experienced with this library.

What I want to do:

  1. Add private field of given type to Class1
  2. Initialize this field in the Class1 constructor (didn't get here yet :) )

My code is:

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
        }
    }
}

After it's done, this is what I see in ILSpy:

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

    // Methods
...

testInt was added by myself directly in C# before processing the library with Mono.Cecil. It's identical to what Mono.Cecil generated for addedField. However, when I try loading this modified assembly using Console application it throw TypeLoadException saying: non-static global field.

Any ideas?

1 Answers1

2

I will answer myself as I found the solution some time back, maybe someone will find it useful. This is the part which caused my pain:

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

After reading this post: What is the "<Module>" type? I realized I'm adding some field to <Module> type in fact, and that caused me my troubles. After changing my logic to add new field to specified classes only it worked as expected.