Создать экземпляр класса по его текстовому названию - PullRequest
33 голосов
/ 24 марта 2012

Не спрашивайте меня, почему, но мне нужно сделать следующее:

string ClassName = "SomeClassName";  
object o = MagicallyCreateInstance("SomeClassName");

Я хочу знать, сколько существует способов сделать это и какой подход использовать в каком сценарии.

Примеры:

  • Activator.CreateInstance
  • Assembly.GetExecutingAssembly.CreateInstance("")
  • Буду признателен за любые другие предложения

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

Ответы [ 2 ]

48 голосов
/ 25 марта 2012

Вот как может выглядеть метод:

private static object MagicallyCreateInstance(string className)
{
    var assembly = Assembly.GetExecutingAssembly();

    var type = assembly.GetTypes()
        .First(t => t.Name == className);

    return Activator.CreateInstance(type);
}

Приведенный выше код предполагает, что:

  • вы ищете класс, который находится в текущей выполняемой сборке (этоможно настроить - просто измените assembly на все, что вам нужно)
  • есть ровно один класс с именем, которое вы ищете в этой сборке
  • класс имеет конструктор по умолчанию

Обновление:

Вот как получить все классы, производные от данного класса (и определенные в одной сборке):

private static IEnumerable<Type> GetDerivedTypesFor(Type baseType)
{
    var assembly = Assembly.GetExecutingAssembly();

    return assembly.GetTypes()
        .Where(baseType.IsAssignableFrom)
        .Where(t => baseType != t);
}
17 голосов
/ 25 марта 2012
Activator.CreateInstance(Type.GetType("SomeNamespace.SomeClassName"));

или

Activator.CreateInstance(null, "SomeNamespace.SomeClassName").Unwrap();

Существуют также перегрузки, в которых вы можете указать аргументы конструктора.

...