3

I am trying to add new overloaded constructor to an existing type. I tried to do it with emit namespace, however created type doesnt inherit the base class and all other methods.

And after reading some articles, i decided its not possible with .net framework built-in classes.

So I got Mono.Cecil, but couldnt find any decent example how to achieve this.

I have encountered a sample which copies methods, but not props, fields etc.

kvb
  • 54,864
  • 2
  • 91
  • 133
user1934537
  • 49
  • 1
  • 5
  • Could you explain why are you trying to do this? Which type are you talking about? Also, what have you tried? How did that fail? – svick Dec 28 '12 at 14:01
  • public class Parent : Child { public Parent(int x, int y) : base(x, y) { } //other stuff } basically, I am trying add this constructor. I tried something like this: http://msdn.microsoft.com/en-us/library/system.reflection.emit.constructorbuilder(v=vs.71).aspx However after invoking new constructor the object is not inherited from Child class, but object class itself. however, base constructor is called in debug. emit codes were something like this: (ignore cecil convention) – user1934537 Dec 28 '12 at 14:28
  • ctorIL.Append(ctorIL.Create(Mono.Cecil.Cil.OpCodes.Ldarg_0)); ctorIL.Append(ctorIL.Create(Mono.Cecil.Cil.OpCodes.Ldarg_1)); ctorIL.Append(ctorIL.Create(Mono.Cecil.Cil.OpCodes.Ldarg_2)); ctorIL.Append(ctorIL.Create(Mono.Cecil.Cil.OpCodes.Call, baseMethod)); ctorIL.Append(ctorIL.Create(Mono.Cecil.Cil.OpCodes.Ret)); – user1934537 Dec 28 '12 at 14:33
  • So right now, I am gonna try something like this: -Hook Assembly.Resolve event -Find types inherited from Child -Add constructor for each type with Mono.Cecil -Write new assembly to a file -Load the new assembly file Am I in the right path? Or is there another way to do this? – user1934537 Dec 28 '12 at 14:39

1 Answers1

8

This adds an empty constructor

void AddEmptyConstructor(TypeDefinition type, MethodReference baseEmptyConstructor)
{
    var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
    var method = new MethodDefinition(".ctor", methodAttributes, ModuleDefinition.TypeSystem.Void);
    method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
    method.Body.Instructions.Add(Instruction.Create(OpCodes.Call, baseEmptyConstructor));
    method.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
    type.Methods.Add(method);
}

You will need to extend it to pass through the extra parameters.

From here

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
Simon
  • 33,714
  • 21
  • 133
  • 202