Подтвердить что ты не робот

С# экземпляр класса из строки

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

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

Кроме того...

String childClassString;
MyAbstractClass myObject;

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

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

4b9b3361

Ответ 1

Посмотрите на Activator.CreateInstance().

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

или

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

Ответ 2

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

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

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

edit: забыли перевести на MyAbstractClass

Ответ 3

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

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

Если вы ответите так, как указано в ответах здесь: Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName), вместо этого он возвращает ObjectHandle, и вам нужно вызвать Unwrap() на нем, чтобы получить ваш объект. Эта перегрузка полезна при попытке вызова метода, определенного в другой сборке (BTW, вы можете использовать эту перегрузку в текущей сборке, просто оставьте параметр 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();