Instantiating a constructor with parameters in an internal class with reflection

C#Reflection

C# Problem Overview


I have something along the lines of this:

object[] parameter = new object[1];
parameter[0] = x;
object instantiatedType =
Activator.CreateInstance(typeToInstantiate, parameter);

and

internal class xxx : ICompare<Type>
{
    private object[] x;

    # region Constructors

    internal xxx(object[] x)
    {
        this.x = x;
    }

    internal xxx()
    {
    }

    ...
}

And I get:

threw exception: System.MissingMethodException: Constructor on type 'xxxx.xxx' not found..

Any ideas?

C# Solutions


Solution 1 - C#

The issue is that Activator.CreateInstance(Type, object[]) does not consider non-public constructors.

> Exceptions > > MissingMethodException: No matching > public constructor was found.

This is easily shown by changing the constructor to publicvisibility; the code then works correctly.

Here's one workaround (tested):

 BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
 CultureInfo culture = null; // use InvariantCulture or other if you prefer
 object instantiatedType =   
   Activator.CreateInstance(typeToInstantiate, flags, null, parameter, culture);

If you only require the parameterless constructor this will work as well:

//using the overload: public static object CreateInstance(Type type, bool nonPublic)
object instantiatedType = Activator.CreateInstance(typeToInstantiate, true)

Solution 2 - C#

(tested successfully)

object instantiatedType =
   Activator.CreateInstance(typeToInstantiate,
   System.Reflection.BindingFlags.NonPublic |
     System.Reflection.BindingFlags.Instance,
   null, new object[] {parameter}, null);

There are two issues this addresses:

  • the new object[] {parameter} helps it handle the issue of passing an object[] as a single parameter of method that takes a params object[] argument
  • the BindingFlags helps resolve the non-public constructor

(the two nulls relate to the binder; the default binder behaviour is fine for what we want)

Solution 3 - C#

You need to call a different overload of Activator.CreateInstance that lets you pass a nonPublic or BindingFlags parameter.

I find all these CreateInstance overloads clumsy; what I prefer to do is:

  1. Call typeToInstantiate.GetConstructor(), passing BindingFlags.NonPublic
  2. Call ConstructorInfo.Invoke, passing it the constructor parameter

Solution 4 - C#

change it to

Activator.CreateInstance(typeToInstantiate,new object[] { parameter });

This is because your constructor also expects an object array and activator already splits it up into separate objects

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKP65View Question on Stackoverflow
Solution 1 - C#AniView Answer on Stackoverflow
Solution 2 - C#Marc GravellView Answer on Stackoverflow
Solution 3 - C#Tim RobinsonView Answer on Stackoverflow
Solution 4 - C#DoggettView Answer on Stackoverflow