Есть ли способ создать экземпляр класса, основанный на том факте, что я знаю имя класса во время выполнения. По сути, я бы назвал класс в виде строки.
Есть ли способ создать экземпляр класса, основанный на том факте, что я знаю имя класса во время выполнения. По сути, я бы назвал класс в виде строки.
Ответы:
Взгляните на метод Activator.CreateInstance .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Это довольно просто. Предположим, что ваше имя класса 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);
dynamic
код - см. Stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
с str
, fullyQualifiedName
будет делать эту работу.
str
используется как часть соглашения об именовании переменных. Некоторые организации и проекты настаивают на том, чтобы следовать этому, поэтому я использовал. Если бы вы работали в определенных организациях / проектах, вы будете знать это. Как вы сказали и без str
него, он тоже сделает свою работу :) @MehdiDehghani
Я успешно использовал этот метод:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Вам нужно привести приведенный объект к нужному типу объекта.
Возможно, мой вопрос должен был быть более конкретным. Я на самом деле знаю базовый класс для строки, поэтому решил его следующим образом:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Класс Activator.CreateInstance имеет различные методы для достижения одного и того же по-разному. Я мог бы привести его к объекту, но вышеизложенное наиболее полезно для моей ситуации.
Я знаю, что опаздываю к игре ... но решение, которое вы ищете, может быть комбинацией вышеперечисленного и использованием интерфейса для определения ваших объектов публично доступных аспектов.
Затем, если все ваши классы, которые будут сгенерированы таким образом, реализуют этот интерфейс, вы можете просто привести их как тип интерфейса и работать с результирующим объектом.
Чтобы создать экземпляр класса из другого проекта в решении, вы можете получить сборку, указанную именем любого класса (например, BaseEntity), и создать новый экземпляр:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Например, если вы храните значения различных типов в поле базы данных (хранятся в виде строки) и имеете другое поле с именем типа (т. Е. String, bool, int, MyClass), то из данных этого поля вы можете, предположительно, создайте класс любого типа, используя приведенный выше код, и заполните его значением из первого поля. Это, конечно, зависит от типа, который вы храните, имея метод для анализа строк в правильный тип. Я использовал это много раз, чтобы сохранить настройки пользовательских настроек в базе данных.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
почему вы хотите написать такой код? Если у вас есть класс ReportClass, вы можете создать его экземпляр напрямую, как показано ниже.
ReportClass report = new ReportClass();
Код ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
используется, когда у вас нет необходимого класса, но вы хотите создать экземпляр и / или вызвать метод динамически.
Я имею в виду, что это полезно, когда вы знаете сборку, но при написании кода у вас нет ReportClass
доступного класса .