Can't find constructor on type; works in Watch
This is the code I use:
Type type = /* retrieved Type */
object arg = /* something that evaluates to null */
MyClass obj = (MyClass)Activator.CreateInstance(type, arg);
I get a crash, that given constructor doesn't exist on type type.
However, when I put this in Watch in Visual Studio 2008:
(MyClass)System.Activator.CreateInstance(type, null)
it creates the object as usual.
I even tried replacing my code with the one I put in the Wa开发者_StackOverflow中文版tch. It works - object gets created.
My question: what's up with that?
Edit: MyClass doesn't have any constructors - apart from pregenerated parameterless constructor.
Edit 2: Using new object[0]
instead of null
still causes the same exception.
Your code is using the following overload of the Activator.CreateInstance Method:
public static Object CreateInstance(
Type type,
params Object[] args
)
Notice the params
keyword.
Now let's take a look at your code:
Activator.CreateInstance(type, null)
This passes a null reference as args
. In this case, the method looks for a parameter-less constructor.
object arg = // ...
Activator.CreateInstance(type, arg)
This passes a one-element array containing a null reference as args
, because arg
is declared as object
. In this case, the method looks for a constructor with one parameter.
To avoid any ambiguity, call the method as follows:
object[] args = null; // 0 parameters
// - or -
object[] args = new object[] { "Hello World" }; // 1 parameter
var result = (MyClass)Activator.CreateInstance(type, args);
You've run into an issue with the params
keyword.
The actual signature of the function is CreateInstance(Type, object[])
. However, the fact that the object[]
parameter is declared as params
means that you can pass a variable number of arguments to the function and those arguments will get rolled into a new array, or you can directly pass an object array.
When the compiler performs overload resolution on the version where you pass null
directly into the function, it does not convert the parameter into an array since null
is a valid value for this. However, when you pass in a null-valued object variable, overload resolution has to turn that into an object array. This means that you are passing an object array with one value, which is null
. The runtime then looks for a constructor with one argument, which it would then pass null
to.
This is why the resolution fails at runtime.
精彩评论