开发者

Can't find constructor on type; works in Watch

开发者 https://www.devze.com 2023-03-14 07:53 出处:网络
This is the code I use: Type type = /* retrieved Type */ object arg = /* something that evaluates to null */

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消