Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating a constructor with parameters in an internal class with reflection

Tags:

c#

reflection

People also ask

How do you instantiate an internal class?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass outerObject = new OuterClass(); OuterClass. InnerClass innerObject = outerObject.

How to create an Instance of a class in java reflection?

We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.

Can constructor be internal in C#?

Instance constructorInstance constructors can have public, private, protected, external, or internal modifiers.

Can constructor be internal?

Constructor code or any internal method used only by constructor are not included in final code. A constructor can be either public or internal.


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)

(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)


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

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