2010-05-13 3 views
2

У меня есть следующий абстрактный класс, который НЕ МОЖЕТ быть изменен.Динамическое переопределение абстрактного метода в C#

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

Теперь я хотел бы реализовать некоторые новые динамические типы из-за этого.

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); 

Однако, когда я пытаюсь создать экземпляр через

typeBuilder.CreateType(); 

я получаю исключение о том, что нет реализации для GetName. Что-то я здесь делаю неправильно. Я не вижу проблемы.

Также были бы ограничения на создание экземпляра такого класса по имени? Например, если я попытался создать экземпляр через «My.TempAssembly.x_Thing», будет ли он доступен для создания экземпляра без генерируемого типа?

+0

Что вы имеете в виду под «инстанцировании такой класс по имени»? Если вы не включаете сгенерированную сборку в свою сборку, вы не можете напрямую ссылаться на ее типы в своей программе. Вам нужно будет использовать Reflection или 'Activator.CreateInstance (Type)'. –

+0

Да, это именно то, что я имею в виду, Type.GetType («My.TempAssembly.x_Thing»), затем на Activator.CreateInstance (type). Он работал нормально. –

ответ

8

У вас неправильный тип возврата для динамически созданной функции. Это должно быть string вместо void:

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

Вместо этого я использовал бы Func. Это не требует отражения для динамического изменения метода.

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"; 
+0

На самом деле это не тот ответ, который я ищу, AbstractThing не может быть изменен. Цель - строковый результат My.TempAssembly.x_Thing, который я могу создать динамически. –

+0

Это не отвечает на вопрос, и ему понадобится Func, а не Action –

+0

Я знаю, что он не отвечает на вопрос напрямую, а просто другим способом. – Dykam

Смежные вопросы