Не могу найти конструктор по типу;работает в Watch - PullRequest
4 голосов
/ 22 июня 2011

Это код, который я использую:

Type type = /* retrieved Type */
object arg = /* something that evaluates to null */
MyClass obj = (MyClass)Activator.CreateInstance(type, arg);

Я получаю сбой, указанный конструктор не существует для типа тип .

Однако, когдаЯ поместил это в Watch в Visual Studio 2008:

(MyClass)System.Activator.CreateInstance(type, null)

он создает объект как обычно.

Я даже попытался заменить свой код тем, который я вставил в Watch.Это работает - объект создается.

Мой вопрос: что с этим?

Редактировать: MyClass не имеет никаких конструкторов - кромеиз предварительно сгенерированного конструктора без параметров .

Редактировать 2: Использование new object[0] вместо null все еще вызывает то же исключение.

Ответы [ 2 ]

4 голосов
/ 22 июня 2011

Ваш код использует следующую перегрузку Activator.CreateInstance Method :

public static Object CreateInstance(
    Type type,
    params Object[] args
)

Обратите внимание на ключевое слово params.

Теперь давайте посмотримна ваш код:

Activator.CreateInstance(type, null)

Это передает нулевую ссылку как args.В этом случае метод ищет конструктор без параметров.

object arg = // ...
Activator.CreateInstance(type, arg)

Передается одноэлементный массив, содержащий нулевую ссылку как args, поскольку arg объявлено как object.В этом случае метод ищет конструктор с одним параметром.

Чтобы избежать двусмысленности, вызовите метод следующим образом:

object[] args = null;                            // 0 parameters
//  - or -
object[] args = new object[] { "Hello World" };  // 1 parameter

var result = (MyClass)Activator.CreateInstance(type, args);
2 голосов
/ 22 июня 2011

Вы столкнулись с проблемой с ключевым словом params.

Фактическая подпись функции - CreateInstance(Type, object[]).Однако тот факт, что параметр object[] объявлен как params, означает, что вы можете передать функции переменное число аргументов, и эти аргументы будут свернуты в новый массив, или , который вы можете напрямуюпередать массив объектов.

Когда компилятор выполняет разрешение перегрузки для версии, в которой вы передаете null непосредственно в функцию, он не преобразует параметр в массив, поскольку null является допустимым значением для этого.Однако, когда вы передаете объектную переменную с нулевым значением , разрешение перегрузки должно превратить это в массив объектов.Это означает, что вы передаете массив объектов с одним значением, равным null.Затем среда выполнения ищет конструктор с одним аргументом, который он затем передает null.

Вот почему разрешение не выполняется во время выполнения.

...