Создать экземпляр класса из строки - PullRequest
193 голосов
/ 22 октября 2008

Есть ли способ создать экземпляр класса, основанный на том факте, что я знаю имя класса во время выполнения. По сути, у меня будет имя класса в строке.

Ответы [ 9 ]

148 голосов
/ 22 октября 2008

Взгляните на метод Activator.CreateInstance .

58 голосов
/ 25 ноября 2014

Это довольно просто. Предположим, что ваше имя класса Car и пространство имен Vehicles, затем передайте параметр как Vehicles.Car, который возвращает объект типа Car. Таким образом, вы можете динамически создавать любой экземпляр любого класса.

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}

Если ваше Полное имя (т.е. Vehicles.Car в данном случае) находится в другой сборке, Type.GetType будет нулевым. В таких случаях вы просматриваете все сборки и находите Type. Для этого вы можете использовать следующий код

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

Теперь, если вы хотите вызвать параметризованный конструктор , сделайте следующее

Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type

вместо

Activator.CreateInstance(t);
52 голосов
/ 22 октября 2008

Я успешно использовал этот метод:

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)

Вам необходимо привести приведенный объект к нужному типу объекта.

20 голосов
/ 22 октября 2008

Возможно, мой вопрос должен был быть более конкретным. Я на самом деле знаю базовый класс для строки, поэтому решил ее следующим образом:

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

Класс Activator.CreateInstance имеет различные методы для достижения одной и той же цели различными способами. Я мог бы привести его к объекту, но вышесказанное наиболее полезно для моей ситуации.

4 голосов
/ 17 ноября 2012

Я знаю, что опаздываю к игре ... но решение, которое вы ищете, может заключаться в комбинации перечисленного выше и использовании интерфейса для определения общедоступных аспектов ваших объектов.

Тогда, если все ваши классы, которые будут сгенерированы таким образом, реализуют этот интерфейс, вы можете просто привести его как тип интерфейса и работать с результирующим объектом.

3 голосов
/ 23 сентября 2010

Например, если вы храните значения различных типов в поле базы данных (хранятся в виде строки) и имеете другое поле с именем типа (например, String, bool, int, MyClass), то из данных этого поля вы можете возможно, создайте класс любого типа, используя приведенный выше код, и заполните его значением из первого поля. Это, конечно, зависит от типа, который вы храните, имея метод для анализа строк в правильный тип. Я использовал это много раз, чтобы сохранить настройки пользовательских настроек в базе данных.

3 голосов
/ 22 октября 2008

Вы, кажется, описали решение, которое хотите реализовать, но не проблему, которую пытаетесь решить.

Возможно, вы пытаетесь сделать что-то с расширяемостью, и в этом случае я предлагаю вам ознакомиться с Managed Extensibility Framework .

2 голосов
/ 19 декабря 2018

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

  var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
0 голосов
/ 11 мая 2010
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

почему вы хотите написать такой код? Если у вас есть класс ReportClass, вы можете создать его экземпляр, как показано ниже.

ReportClass report = new ReportClass();

Код ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass)); используется, когда у вас нет необходимого класса, но вы хотите создать экземпляр и / или вызвать метод динамически.

Я имею в виду, что это полезно, когда вы знаете сборку, но при написании кода у вас нет класса ReportClass.

...