这是我使用的代码:
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
仍会导致相同的异常。
答案 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
。
这就是解决方案在运行时失败的原因。