这是我使用的代码:
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)
它像往常一样创建对象。
我甚至试着用我放在手表里的代码替换我的代码。它工作——对象被创建。
我的问题是:怎么了?
编辑:除了预生成的无参数构造函数外,MyClass没有任何构造函数。
编辑2:使用new object[0]
而不是null
仍然会导致相同的异常。
您的代码正在使用Activator.CreateInstance方法的以下重载:
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);
您遇到了params
关键字的问题。
函数的实际签名是CreateInstance(Type, object[])
。但是,object[]
参数被声明为params
,这意味着您可以向函数传递可变数量的参数,这些参数将被滚动到一个新数组中,或您可以直接传递一个对象数组。
当编译器对将null
直接传递到函数中的版本执行重载解析时,它不会将参数转换为数组,因为null
是一个有效值。但是,当您传入一个空值的对象变量时,重载解析必须将其转换为一个对象数组。这意味着您正在传递一个具有一个值的对象数组,即null
。然后,运行库查找一个带有一个参数的构造函数,然后将null
传递给.
这就是解析在运行时失败的原因。