Отражение С#: создание экземпляра объекта, у которого нет конструктора по умолчанию

Я знаю, что FormatterServices.GetUninitializedObject может это сделать, но базовая библиотека для xbox не содержит этого класса.

Я работаю над игрой XNA, и я пытаюсь заставить это работать там. Activator.CreateInstance доступен, но мне нужен конструктор по умолчанию, что некрасиво.

Я подумал, что если нет конструктора по умолчанию, я беру самый короткий и передаю любые значения (например, когда для этого требуются int и object, я передаю 0 и null). Но проблема в том, что конструктор может генерировать исключение, если он работает с переданными объектами. Ну, я все еще мог бы написать это в блоке try catch, и, возможно, он работает таким образом. Но вряд ли я бы так поступил. Есть ли другое решение?

Спасибо за любую помощь :)


person Community    schedule 23.03.2013    source источник
comment
Почему вы хотите это сделать?   -  person bash0r    schedule 23.03.2013
comment
Что бы вы сделали с объектом, который не инициализирован должным образом?   -  person Guffa    schedule 23.03.2013


Ответы (3)


Вам не нужен конструктор по умолчанию, я думаю, что есть перегрузка, в которой вы можете передавать параметры в

Activator.CreateInstance (typeof (Foo), new object []{  args});

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

Редактировать: подождите - перечитывая вопрос, вы говорите, что не знаете, что передать? Тогда зачем вы его создаете?

person JerKimball    schedule 23.03.2013
comment
Это сработало. Спасибо чувак. -- Не знаю, что происходит с Visual Studio в последнее время, похоже, он должен был показать мне эту перегрузку -- до сих пор не могу найти ее в интеллектуальном смысле, кстати, -- но она работает, так что это здорово. :-) - person BrainSlugs83; 28.08.2015

Нет, это совершенно неправильное решение.

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

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

Поскольку вы прибегаете к Activator.CreateInstance, я предполагаю, что вы мало что знаете о рассматриваемом типе, кроме его объекта Type. В этом (общем) случае вы не должны просто передавать некоторые нечетные значения в конструктор в надежде, что это будет иметь смысл для рассматриваемого типа.

Если, с другой стороны, у вас есть какой-то контракт, в котором вы можете сказать: «Я знаю, что этот тип поддерживает контракт X», вы можете изучить использование интерфейса и вызов метода в этом интерфейсе после создания объекта. Затем интерфейс будет иметь известный метод (известный коду, который должен создать экземпляр), который вы вызовете с помощью известного (известного как знание количества, их типов, а также их значения) параметры.

Просто случайным образом (передача 0 и null только для соответствия подписи так же произвольна, как передача 42 и какого-то странного объекта) передача параметров в конструктор небезопасна совсем.

Пример с интерфейсом:

object instance = Activator.CreateInstance(someTypeObject);
((ISomeInterface)instance).Initialize(your, specific, parameters, here);

Что вам может понадобиться, так это структура IoC, чтобы вы могли сказать: «Всякий раз, когда кому-то нужен экземпляр этого класса, вот как его построить».

Погляди:

person Lasse V. Karlsen    schedule 23.03.2013
comment
Я работаю над пользовательским сериализатором. И мне нужно получить экземпляр, когда я десериализую. Так что мне все равно, если созданный объект имеет странные значения, мне просто нужен экземпляр. И когда у меня есть экземпляр, я устанавливаю значения с сохранением других значений. - person ; 23.03.2013
comment
Вам может быть все равно, но тип будет иметь значение, поэтому он был создан без конструкторов без параметров. Если у типа нет конструкторов, пригодных для десериализации, тип не предназначен для сериализации. Смените тип! - person Lasse V. Karlsen; 23.03.2013
comment
@LasseV.Karlsen - посмотрите ответ JerKimball ниже, а также этот метод: msdn.microsoft.com/en-us/library/wcxyzt4d(v=vs.110).aspx - person Tohid; 02.05.2014
comment
@Tohid Я не вижу связи. Вопрос явно задавал что-то, что автоматически выбирало конструктор a и просто передало значение по умолчанию для каждого параметра. Возможность выбрать конструктор путем передачи значений не является ответом, потому что это то, чего ОП явно просил избегать. И если вы прочитаете ответ его (ДжерКимбалла), вы увидите, что он тоже это понял. Мой вопрос в том, что вы видите, чего не видим мы? - person Lasse V. Karlsen; 02.05.2014
comment
@LasseV.Karlsen - Понятно. Спасибо за объяснение. - person Tohid; 28.05.2014

Вы заявляете, что ваш целевой класс не имеет конструктора по умолчанию (или "без параметров"). Перефразируй; конструктор вашего класса содержит «Зависимости». Он не может (и не должен!) быть построен до тех пор, пока не будут соблюдены эти зависимости.

Вам нужен контейнер Dependency Injection (или Inversion of Control). Я рекомендую присмотреться к Ninject из-за отличной реализации, которая оказывается совместимой с XNA.

Платформы внедрения зависимостей позволяют вам указывать общие «правила», чтобы контейнер внедрения зависимостей мог «заполнять пробелы», когда вы сталкиваетесь с объектом, для которого требуются параметры в конструкторе. Например, пример правила DI для создания типа Foo: «Когда вы пытаетесь создать объект типа Foo, у которого есть конструктор с параметрами (int, object), передайте в конструктор следующие значения: (0, null). "

Потратьте немного времени на просмотр некоторых примеров по предоставленной ссылке, чтобы понять, как добиться того, о чем вы просите, с помощью библиотеки Ninject.

person BTownTKD    schedule 23.03.2013
comment
Комментарии дают контекст отрицательных голосов. Особенно, когда ответ, за который проголосовали, сказал то же самое... 3 минуты спустя. - person BTownTKD; 23.03.2013
comment
Мое отрицательное мнение: это не отвечает на вопрос и не решает проблему, о которой спрашивает ОП. - person Kieren Johnstone; 23.03.2013
comment
@KierenJohnstone - ОП спросил, как создать экземпляр объекта, у которого нет конструктора по умолчанию/без параметров. Перефразируй; рассматриваемый конструктор содержит зависимости. Таким образом, мой ответ — что он может использовать инфраструктуру внедрения зависимостей для создания экземпляров таких объектов — не только актуален, но и считается передовой практикой среди разработчиков .NET. - person BTownTKD; 24.03.2013