4

这是我使用的代码:

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

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

但是,当我将其放入 Visual Studio 2008 中的 Watch 中时:

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

它像往常一样创建对象。

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

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

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

编辑2:使用new object[0]而不是null仍然会导致相同的异常。

4

2 回答 2

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)

这将传递一个包含空引用的单元素数组 as args,因为arg被声明为object。在这种情况下,该方法会查找具有一个参数的构造函数。

为避免任何歧义,请按如下方式调用该方法:

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

var result = (MyClass)Activator.CreateInstance(type, args);
于 2011-06-21T22:11:15.007 回答
2

您遇到了params关键字问题。

该函数的实际签名是CreateInstance(Type, object[]). object[]但是,参数被声明为这一事实params意味着您可以将可变数量的参数传递给函数,这些参数将被滚动到一个新数组中,或者您可以直接传递一个对象数组。

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

这就是解析在运行时失败的原因。

于 2011-06-21T22:19:14.083 回答