Создавать экземпляр класса из его текстового имени

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

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

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

Примеры:

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

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

Ответ 1

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

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

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

    return Activator.CreateInstance(type);
}

В приведенном выше коде предполагается, что:

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

Update:

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

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

    return assembly.GetTypes()
        .Where(baseType.IsAssignableFrom)
        .Where(t => baseType != t);
}

Ответ 2

Activator.CreateInstance(Type.GetType("SomeNamespace.SomeClassName"));

или

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

Есть также перегрузки, где вы можете указать аргументы конструктора.