Есть ли способ создать экземпляр класса, основанный на том, что я знаю имя класса во время выполнения. В основном я бы назвал класс в строке.
Создайте экземпляр класса из строки
Ответ 1
Посмотрите на метод Activator.CreateInstance.
Ответ 2
Это довольно просто. Предположим, что ваше имя класса Car
и пространство имен Vehicles
, затем передайте параметр как Vehicles.Car
, который возвращает объект типа Car
. Подобным образом вы можете создать любой экземпляр любого класса динамически.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Если ваше Полностью квалифицированное имя (т.е. Vehicles.Car
в этом случае) находится в другой сборке, Type.GetType
будет иметь значение null. В таких случаях вы прокручиваете все сборки и находите 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);
Ответ 3
Я успешно использовал этот метод:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Вам нужно будет вернуть возвращенный объект к вашему желаемому типу объекта.
Ответ 4
Возможно, мой вопрос должен был быть более конкретным. Я действительно знаю базовый класс для строки, поэтому решил ее:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Класс Activator.CreateInstance имеет различные методы для достижения того же самого по-разному. Я мог бы отнести его к объекту, но вышеупомянутое наиболее полезно для моей ситуации.
Ответ 5
Я знаю, что я опаздываю на игру... но решение, которое вы ищете, может быть комбинацией вышеизложенного и использование интерфейса для определения ваших объектов общедоступными аспектами.
Затем, если все ваши классы, которые будут сгенерированы таким образом, реализуют этот интерфейс, вы можете просто ввести в качестве типа интерфейса и работать с результирующим объектом.
Ответ 6
Кажется, вы описали решение, которое хотите реализовать, но не проблему, которую вы пытаетесь решить.
Возможно, вы пытаетесь сделать что-то с расширяемостью, и в этом случае я предлагаю вам проверить Managed Extensibility Framework.
Ответ 7
Например, если вы сохраняете значения различных типов в поле базы данных (хранятся как строки) и имеете другое поле с именем типа (т.е. String, bool, int, MyClass), то из этих данных поля вы можете, предположительно, создать класс любого типа с использованием вышеуказанного кода и заполнить его значением из первого поля. Это, конечно, зависит от типа, который вы храните, имея метод для синтаксического анализа строк в правильном типе. Я использовал это много раз, чтобы сохранить настройки пользовательских предпочтений в базе данных.
Ответ 8
Чтобы создать экземпляр класса из другого проекта в решении, вы можете получить сборку, указанную именем любого класса (например, BaseEntity), и создать новый экземпляр:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Ответ 9
Мне нужно создать экземпляр из выпадающего значения, которое указывает на Enum. Enum имеет точное имя как имена классов.
Type.GetType("Device.Core.Package."+cmbdropdowm.SelectedItem.ToString()+",Device.Core");
Приведенный выше код работает для меня.
Ответ 10
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
почему вы хотите написать такой код? Если у вас есть класс "ReportClass", вы можете создать его непосредственно, как показано ниже.
ReportClass report = new ReportClass();
Код ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
используется, когда у вас нет необходимого класса, но вы хотите динамически создавать и/или вызывать метод.
Я имею в виду, что это полезно, когда вы знаете сборку, но при написании кода у вас нет класса ReportClass
.