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


168

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

137

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

+14

Связанные с большими примерами: HTTP : //stackoverflow.com/questions/493490/converting-a-string-to-a-class-name 24 апр. 132013-04-24 14:23:37

  0

Также это сообщение будет актуальным, так как ваш тип должен быть найден: http: // st ackoverflow.com/questions/1825147/type-gettypenamespace-ab-classname-returns-null 23 авг. 132013-08-23 20:48:13

+4

Например: ' var driver = (OpenQA.Selenium.IWebDriver) Activator.CreateInstance («WebDriver», «OpenQA.Selenium.Firefox.FirefoxDriver»). Unwrap(); ' 04 окт. 142014-10-04 04:37:07

+2

Важное примечание здесь: .Unwrap(), чтобы пройти через удаленный дескриптор так вы действительно можете делать броски. @Endy - Спасибо 20 июл. 152015-07-20 01:31:38


49

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

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

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

  0

hm .. получается, что имена пользователей не уникальны. 21 окт. 082008-10-21 23:48:02

+7

Я пытаюсь представить сценарий, когда создание объекта через имя класса, а затем его использование в качестве этого типа могло бы иметь какой-то смысл. 21 окт. 082008-10-21 23:53:35

+11

Я понимаю, что вы имеете в виду. Это кажется излишним. Если вы знаете имя класса, зачем нужна динамическая строка? Одна из ситуаций может заключаться в том, что ваше кастинг в базовый класс и строка представляет потомки этого базового класса. 21 окт. 082008-10-21 23:58:29

+3

Если базовый класс известен, вы можете использовать базовый класс или его интерфейс в качестве аргумента для передачи потомков без отражения. 25 янв. 142014-01-25 09:01:11

+2

Полезный сценарий: вам нужны только интерфейсы сериализации или любой другой довольно общий интерфейс. Вы не будете бросать его в класс, но, по крайней мере, на что-то большее, чем объект 08 дек. 142014-12-08 11:08:49

  0

Xaml при щелчке на новую страницу навигации - прекрасный пример, я могу думать о многом другом. 05 янв. 162016-01-05 19:03:08

+1

Как сделать бросок __ из данной строки__ ?? 25 апр. 162016-04-25 12:00:04


16

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

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

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

+2

Вместо ответа в разделе вопросов я предлагаю вам отредактировать свой вопрос и отметить изменения. Вы получите больше/лучших ответов для этого. 22 окт. 082008-10-22 00:53:45

  0

Спасибо, что опубликовали конкретную строку кода, которая сработала для вас. Сортировка всех перегрузок CreateInstance и различных способов генерации типов занимала у меня много времени, которое вы меня спасли. 05 янв. 112011-01-05 22:01:12


3

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

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


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

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

ReportClass report = new ReportClass(); 

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

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


1

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


4

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

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


37

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

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

Fully Qualified Name Если ваш (т.е. 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); 
  0

Как использовать его без кастинга и как сделать литье __из данной строки__ ?? 25 апр. 162016-04-25 12:16:06

  0

@TaW - чтобы использовать экземпляр класса, вам нужно будет знать, что он собирается делать, иначе вы не сможете его использовать. Наиболее распространенным случаем использования для этого является переключение на некоторый интерфейс, который дает вам предопределенный контракт. (Это выполняется, если вы не используете «динамический» код - см. Http://stackoverflow.com/a/2690661/904521) 25 май. 162016-05-25 08:47:28