在类型上找不到构造函数;适用于Watch

时间:2011-06-21 22:04:01

标签: c# reflection constructor watch

这是我使用的代码:

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

我遇到了崩溃,在类型类型上不存在给定的构造函数。

但是,当我把它放在Visual Studio 2008中的Watch中时:

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

它像往常一样创建对象。

我甚至尝试用我放在Watch中的代码替换我的代码。它有效 - 对象被创建。

我的问题:这是怎么回事?

编辑:MyClass 有任何构造函数 - 除了预生成的无参数构造函数。

编辑2:使用new object[0]代替null仍会导致相同的异常。

2 个答案:

答案 0 :(得分:4)

您的代码正在使用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);

答案 1 :(得分:2)

您遇到了params关键字的问题。

该函数的实际签名是CreateInstance(Type, object[])。但是,object[]参数声明为params的事实意味着您可以将可变数量的参数传递给函数,并且这些参数将被转换为新的数组,

当编译器对您将null直接传递给函数的版本执行重载解析时,它不会将参数转换为数组,因为null是一个有效值。但是,当您传入一个空值对象变量时,重载决策必须将其转换为对象数组。这意味着您传递的对象数组具有一个值null。然后运行时查找带有一个参数的构造函数,然后将其传递给null

这就是解决方案在运行时失败的原因。