Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Activator.CreateInstance(...) is not finding parameterized constructor

Tags:

c#

reflection

Given the following sample code;

class Program
{
    static void Main(string[] args)
    {
        var results = GetChildren().ToList();
    }

    static IEnumerable<MyBaseClass> GetChildren()
    {
        return Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(t => t.BaseType == typeof(MyBaseClass))
            .Select(o => (MyBaseClass)Activator.CreateInstance(o, null));
    }
}

abstract class MyBaseClass
{ }

class MyChildClass : MyBaseClass
{
    public MyChildClass(object paramOne)
    {

    }
}

I'm receiving the following error;

MissingMethodException: Constructor on type 'CreateInstanceCtorIssue.MyChildClass' not found.

However, if I add a parameterless constructor, it creates the objects OK.

I'm trying to work out why the parameter I'm suppying to CreateInstance is not causing it to find the correct constructor. Anyone got any ideas?

like image 920
Chris McAtackney Avatar asked Feb 29 '12 14:02

Chris McAtackney


People also ask

Does activator CreateInstance call constructor?

The Activator. CreateInstance method creates an instance of a type defined in an assembly by invoking the constructor that best matches the specified arguments. If no arguments are specified then the constructor that takes no parameters, that is, the default constructor, is invoked.

What is activator CreateInstance in C#?

Creates an instance of the specified type using the constructor that best matches the specified parameters. CreateInstance(Type, Object[], Object[]) Creates an instance of the specified type using the constructor that best matches the specified parameters.


2 Answers

Basically, the second argument of the method you are calling is a params array. What's happening is that the C# compiler is treating your method-call as though you are passing this argument in using the "unexpanded" form, i.e. by passing a null array-reference. On the other hand, your intent is to use the "expanded" form, i.e. pass a reference to an array containing a single null-reference.

You can coax the compiler to do what you want like this:

// Unexpanded:
Activator.CreateInstance(o, new object[] { null })

// Expanded explictly:
Activator.CreateInstance(o, (object) null )
like image 169
Ani Avatar answered Sep 27 '22 17:09

Ani


You have to pass the constructor parameters:

.Select(o => (MyBaseClass)Activator.CreateInstance(o, new object[] { someParam }));

MyChildClass expects a single parameter of type object for its constructor - you have to pass this parameter within an array.

like image 43
BrokenGlass Avatar answered Sep 27 '22 16:09

BrokenGlass