2010-04-16 66 views
0

我有下面的类(如通过反射镜看到的)调用“内部外部的”构造函数使用反射

public class W : IDisposable 
{ 
    public W(string s); 
    public W(string s, byte[] data); 

    // more constructors 

    [MethodImpl(MethodImplOptions.InternalCall)] 
    internal extern W(string s, int i); 

    public static W Func(string s, int i); 

} 

我想称之为“内部外部的”构造函数或函数功能使用反射

MethodInfo dynMethod = typeof(W).GetMethod("Func", BindingFlags.Static);     
object[] argVals = new object[] { "hi", 1 }; 
dynMethod.Invoke(null, argVals); 

Type type = typeof(W); 
Type[] argTypes = new Type[] { typeof(System.String), typeof(System.Int32) }; 
ConstructorInfo dynMethod = type.GetConstructor(BindingFlags.InvokeMethod | BindingFlags.NonPublic, null, argTypes, null); 
object[] argVals = new object[] { "hi", 1 }; 
dynMethod.Invoke(null, argVals); 

不幸的是,两种变体在尝试调用时都会出现NullReferenceException,所以,我一定做错了什么?

+0

你用调试器检查了什么是空的?它是'dynMethod'吗? – OregonGhost 2010-04-16 16:48:31

+0

是的,dynMethod在这两个示例中均为空 – Riz 2010-04-16 17:21:24

回答

3

使用Activator通常是不错的主意,但你必须使用具有的BindingFlags作为输入参数调用使用它的内部构造。

在你的代码中有几个不同的错误。您在代码片段和构造函数代码段中都使用错误的BindingFlags,而您使用错误的Invoke方法。这里是应该工作的代码:

MethodInfo dynMethod = typeof(W).GetMethod("Func", BindingFlags.Static | BindingFlags.Public); 
object[] argVals = new object[] { "hi", 1 }; 
dynMethod.Invoke(null, argVals); 


Type type = typeof(W); 
Type[] argTypes = new Type[] { typeof(System.String), typeof(System.Int32) }; 
ConstructorInfo dynMethod = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, argTypes, null); 
object[] argVals = new object[] { "hi", 1 }; 
dynMethod.Invoke(argVals); 

Activator.CreateInstance(typeof(W), BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { "hi", 1 }, null); 
+0

谢谢,你的代码工作出色! – Riz 2010-04-16 17:59:02

+0

出于好奇,为什么你需要CreateInstance和Instance绑定标志?我在这里工作的代码在一个较大的项目中,它没有将任何绑定标志传递给Type.GetConstructor(尽管构造函数是公共的)。 – OregonGhost 2010-04-19 08:21:21

+1

对不起,我在这里误用了'CreateInstance'(代码被修改)。当您调用'Type.InvokeMember'并将成员名称作为字符串传递时,它旨在用于不同的场景。要以这种方式调用构造函数,您不会传递方法名称,而是设置此标志。 'Instance'在这里是重要的标志,因为有静态类构造函数(类型初始化器)这样的事情,我们需要一个实例构造函数。如果您使用Reflector查看'Type.GetConstructor(Type [])'实现,您会看到类似'return this.GetConstructor(BindingFlags.Public | BindingFlags.Instance,null,types,null);' – SergGr 2010-04-19 10:49:04

2

你需要调用Activator.CreateInstance

Activator.CreateInstance(typeof(W), "hi", 1); 
+0

它是否与内部制定者合作?我试过了,但没有奏效。 – Riz 2010-04-16 17:24:12

相关问题