使用反射在内部类中使用参数实例化构造函数

时间:2010-11-02 11:41:57

标签: c# reflection

我有类似的东西:

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

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

    # region Constructors

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

    internal xxx()
    {
    }

    ...
}

我得到了:

抛出异常:System.MissingMethodException:未找到类型为“xxxx.xxx”的构造函数..

有什么想法吗?

4 个答案:

答案 0 :(得分:86)

问题是Activator.CreateInstance(Type, object[])不考虑非公共构造函数。

  

<强>例外

     

MissingMethodException:没有匹配   公共建设者被发现。

通过将构造函数更改为public可见性,可以轻松显示;然后代码可以正常工作。

这是一个解决方法(已测试):

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

如果您只需要无参数构造函数,那么它也可以正常工作:

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

答案 1 :(得分:24)

(测试成功)

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

这有两个问题:

  • new object[] {parameter}有助于它处理将object[]作为参数传递params object[]参数的方法
  • 的问题
  • BindingFlags有助于解决非公开构造函数

(两个null活页夹相关;默认的活页夹行为适用于我们想要的内容。

答案 2 :(得分:4)

您需要致电a different overload of Activator.CreateInstance,以便传递nonPublicBindingFlags参数。

我发现所有这些CreateInstance重载都很笨拙;我更喜欢做的是:

  1. 致电typeToInstantiate.GetConstructor(),传递BindingFlags.NonPublic
  2. 调用ConstructorInfo.Invoke,传递构造函数参数

答案 3 :(得分:1)

将其更改为

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

这是因为你的构造函数还期望一个对象数组和激活器已经将它分成单独的对象