Хобрук: Ваш путь к мастерству в программировании

Конструктор не по умолчанию для типа, определенного во время выполнения

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

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

То есть у меня есть BaseClass и различные дочерние классы.

Type type; //this variable will be one of the child classes
BaseClass base = Activator.CreateInstance(type);

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



Ответы:


1

Три варианта:

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

Лично мне нравится первый вариант, поскольку он дает вам наибольший контроль (вместо того, чтобы полагаться на Activator.CreateInstance поиск наиболее подходящего конструктора во время выполнения) - и если это чувствительный к производительности код, вы можете создать словарь делегатов во время выполнения, обнаружение конструкторов, а затем использование деревьев выражений. (Насколько я могу судить, вы не можете создать делегат из конструктора с использованием Delegate.CreateDelegate, что несколько раздражает.)

02.01.2013

2

Для этого можно использовать Activator.CreateInstance(Type, Object[]) перегрузку. Он вызовет наиболее подходящий конструктор на основе предоставленных параметров.

Например:

public class Test{
 public Test(){
    Console.WriteLine("Defaul ctor");
 }

 public Test(int i){
    Console.WriteLine("Test(int)");
 }

 public  Test(int i, string s){
    Console.WriteLine("Test(int, string)");
 }
}

public static void Main()
{
    var o1 = Activator.CreateInstance(typeof(Test));
    var o2 = Activator.CreateInstance(typeof(Test), 1);
    var o3 = Activator.CreateInstance(typeof(Test), 1, "test");
}
02.01.2013
Новые материалы

Аргументы прогрессивного улучшения почти всегда упускают суть
В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

Введение в Джанго Фреймворк
Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

стройный-i18следующий
Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

Обзор 20 основных и современных методов работы с массивами в JavaScript
Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

Да, но я чувствую необходимость указать, что это или не единственные два.
Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.