Чи є спосіб створити екземпляр класу виходячи з того, що я знаю ім'я класу під час виконання. В основному я б мала назву класу в рядку.
Чи є спосіб створити екземпляр класу виходячи з того, що я знаю ім'я класу під час виконання. В основному я б мала назву класу в рядку.
Відповіді:
Погляньте на метод 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 має різні методи досягнення одного і того ж різними способами. Я міг би кинути його на об'єкт, але вищезазначене найбільше користь для моєї ситуації.
Я знаю, що я запізнююся на гру ... але рішення, яке ви шукаєте, може бути поєднанням перерахованого вище та використанням інтерфейсу для визначення ваших об'єктів загальнодоступними аспектами.
Потім, якщо всі ваші класи, які були б створені таким чином, реалізують цей інтерфейс, ви можете просто представити як тип інтерфейсу та працювати з отриманим об'єктом.
Наприклад, якщо ви зберігаєте значення різних типів у полі бази даних (зберігається як рядок) і маєте інше поле з назвою типу (тобто 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
.