Dynamically overriding an abstract method in C #

I have the following abstract class that CANNOT be modified.

public abstract class AbstractThing {
   public String GetDescription() {
      return "This is " + GetName();
   }
   public abstract String GetName();
}

      

Now I would like to implement some new dynamic types from this.

AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "My.TempAssembly";
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =  assemblyBuilder.DefineDynamicModule("DynamicThings");
TypeBuilder typeBuilder = moduleBuilder.DefineType(someName + "_Thing", 
                TypeAttributes.Public | 
                TypeAttributes.Class, 
                 typeof(AbstractThing));
MethodBuilder methodBuilder = typeBuilder.DefineMethod("GetName",    
                MethodAttributes.Public | 
                MethodAttributes.ReuseSlot |
                MethodAttributes.Virtual | 
                MethodAttributes.HideBySig,
                null,
                Type.EmptyTypes);

ILGenerator msil = methodBuilder.GetILGenerator();

msil.EmitWriteLine(selectionList);
msil.Emit(OpCodes.Ret);

      

However, when I try to instantiate via

typeBuilder.CreateType();

      

I am getting an exception saying there is no implementation for GetName. I am doing something wrong here. I don't see the problem.

Also, what would be the constraints on instantiating such a class by name? For example, if I tried to instantiate via "My.TempAssembly.x_Thing", would it be instantiated without a generated type?

+2


a source to share


2 answers


You have the wrong return type for a dynamically created function. It should be string

instead of void

:



typeBuilder.DefineMethod("GetName",   
MethodAttributes.Public | 
MethodAttributes.ReuseSlot |
MethodAttributes.Virtual | 
MethodAttributes.HideBySig,
typeof(string),
Type.EmptyTypes);

      

+8


a source


I would use Func instead. This does not require reflection to change the method dynamically.



public class AbstractThing {
   public String GetDescription() {
      return "This is " + GetName();
   }
   public Func<String> GetName { get; set; }
}

var thing = new AbstractThing();
thing.GetName = () => "Some Name"; // Or any other method
thing.GetDescription() == "This is Some Name";

      

+3


a source







All Articles