Как создать экземпляр класса с заданным строковым именем?


У меня есть абстрактный класс, и я хочу, чтобы инициализировать его в класс, который расширяет его.

У меня есть имя дочерних классов в виде строки.

кроме этого...

String childClassString;
MyAbstractClass myObject;

if (childClassString = "myExtenedObjectA")
    myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
    myObject = new ExtenedObjectB();

Как я могу это сделать? В основном, как мне избавиться от утверждений if здесь?

3   51   2010-02-11 23:46:26

3 ответа:

смотреть на активатор.CreateInstance ().

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");

или

var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);

Я считаю, что это должно работать:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);

The null в первом параметре по умолчанию используется текущая исполняемая сборка. Для получения дополнительной информации: MSDN

изменить: забыл бросить в MyAbstractClass

у меня были некоторые сложности реализации некоторых ответов здесь, потому что я пытался создать экземпляр объекта из другой сборки (но в том же решении). Поэтому я решил опубликовать то, что нашел для работы.

сначала Activator.CreateInstance метод имеет несколько перегрузок. Если вы просто позвоните Activator.CreateInstance(Type.GetType("MyObj")), что предполагает, что объект определен в текущей сборке, и он возвращает MyObj.

если вы называете его, как рекомендуется в ответах здесь:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName), то вместо возвращает значение ObjectHandle, и вам нужно позвонить Unwrap() на ваш объект. Эта перегрузка полезна при попытке вызвать метод, определенный в другой сборке (кстати, вы можете использовать эту перегрузку в текущей сборке, просто оставьте AssemblyName параметр значение null).

теперь я обнаружил, что предложение выше использовать typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName на AssemblyName на самом деле дал мне ошибки, и я не мог получить, что работать. Я бы получил System.IO.FileLoadException (не удалось загрузить файл или сборку...).

что я получил работать будет следующим образом:

var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();