Reputation: 7189
I have the following abstract class which CAN NOT be changed.
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 like so.
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 get an exception saying that there is no implementation for GetName. Is there something I am doing wrong here. I can not see the problem.
Also, what would be the restrictions on instantiating such a class by name? For instance if I tried to instantiate via "My.TempAssembly.x_Thing" would it be availble for instantiation without the Type generated?
Upvotes: 2
Views: 2497
Reputation: 10300
I would use Func instead. It doesn't require reflection to dynamically change the method.
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";
Upvotes: 2
Reputation: 5414
You have the wrong return type on the 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);
Upvotes: 9