views:

73

answers:

2

Hi, I have following class (as seen through reflector)

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

}

I am trying to call "internal extern" constructor or Func using reflections

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

and

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

unfortunantly both variants rise NullReferenceException when trying to Invoke, so, I must be doing something wrong?

+2  A: 

You need to call Activator.CreateInstance:

Activator.CreateInstance(typeof(W), "hi", 1);
SLaks
Does it work with internal construtors? I tried it, but it didn't work.
Riz
+2  A: 

Using Activator is usually good idea but you have to use a call that has BindingFlags as input parameter to use it for internal constructor.

In you code there are a few of different mistakes. You use wrong BindingFlags in both snippets and in constructor snippet you used wrong Invoke method. Here is code that should work:

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);
iPhone beginner
Thanks, your code is working excellent!
Riz
Out of curiosity, why do you need the CreateInstance and Instance binding flags? I have working code here in a larger project that does not pass any binding flags to Type.GetConstructor (though the constructors are public).
OregonGhost
Sorry, I misused `CreateInstance` here (code is modified). It is intended to be used in different scenario, when you call `Type.InvokeMember` and pass member name as string. To call constructor in such way you don't pass method name but set this flag.`Instance` is important flag here because there is such thing as static class constructor (type initializer) and we need an instance constructor here. If you look at `Type.GetConstructor(Type[])` implementation using Reflector, you'll see something like `return this.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);`
iPhone beginner
Interesting. Didn't think about static constructors when I wrote the code I mentioned. I guess I'm lucky that there I specified parameter types which are only used in my instance constructors :)
OregonGhost
Did you use `GetContructor` that explicitly takes `BindingFlags`? If no, then there is no problem. As I wrote in my previous comment, `GetContructor` methods that don't take `BindingFlags` use `BindingFlags.Public | BindingFlags.Instance` flags i.e. search only for public instance constructor. By the way, there can be only one static constructor and it can't have any parameters. And it is hard to imagine scenario when you might need to call it yourself. Actually I think this is the reason why `GetContructor` returns instance constructors by default.
iPhone beginner