Instantiating a constructor with parameters in an internal class with reflection

后端 未结 4 1837
后悔当初
后悔当初 2020-11-27 18:10

I have something along the lines of this:

object[] parameter = new object[1];
parameter[0] = x;
object instantiatedType =
Activator.CreateInstance(typeToInst         


        
相关标签:
4条回答
  • 2020-11-27 18:46

    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
    0 讨论(0)
  • 2020-11-27 18:50

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

    0 讨论(0)
  • 2020-11-27 18:57

    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)
    
    0 讨论(0)
  • 2020-11-27 19:04

    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

    0 讨论(0)
提交回复
热议问题