Instantiating a constructor with parameters in an internal class with reflection

戏子无情 提交于 2019-12-27 23:36:51

问题


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?


回答1:


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)



回答2:


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




回答3:


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



回答4:


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



来源:https://stackoverflow.com/questions/4077253/instantiating-a-constructor-with-parameters-in-an-internal-class-with-reflection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!