Udostępnij za pośrednictwem


Type.MakeXxxType() (or The Intricacies of Reflection) - a non-NETCF post

The other day someone dropped into my office and asked about the Type.MakeByRefType() method.  Neither I nor my other visitor are experts in reflection on .Net, but we investigated and found the following:

Imagine this situation:

public class foo {``     // Do something with an int.    public void bar(Int32 anArgument) { ... }    // Do something to an int and modify it.    public void bar(ref Int32 aRefArgument) { ... }    // Do something multiple times in one call.    public void bar(Int32[] anArrayArgument) { ... }}

Now say you want to find bar() on type foo via reflection:

    MethodInfo mi = typeof(foo).GetMethod("bar");

To specify the version of bar you want, you need GetMethod(string name, Type[] types).  Okay, so getting the first version is straightforward:

    MethodInfo mi = typeof(foo).GetMethod("bar", new Type[] { typeof(Int32) });

What if you want the second of third overload of bar()?  Well, now you need Type.MakeByRefType() or Type.MakeArrayType() like this:

    MethodInfo mi = typeof(foo).GetMethod("bar", new Type[] { typeof(Int32).MakeByRefType() });

or

    MethodInfo mi = typeof(foo).GetMethod("bar", new Type[] ( typeof(Int32).MakeArrayType() });

Similarly, you can use Type.MakeGenericType() and/or Type.MakePointerType() for other method signatures.

Here's a simple sample:

using System;
using System.Reflection;namespace SAMPLE{    public class foo    {        public foo() {}        public void bar(int arg)        {            Console.WriteLine("bar(int arg):     " + arg.ToString());        }        public void bar(ref int arg)        {            Console.WriteLine("bar(ref int arg): " + arg.ToString());            arg *= arg;            Console.WriteLine("                  " + arg.ToString());        }        public void bar(int[] args)        {            Console.WriteLine("bar(int[] args):  ");            for (int iArg = 0; iArg < args.Length; iArg++)                Console.WriteLine("                 " + args[iArg].ToString());        }    }    public class MakeXxxType    {        static int arg = 1968;        static int refArg = 256;        static int[] argArray = new int[] { 1970, 1995, 2000 };        public static int Main()        {            foo f = new foo();            MethodInfo mi = f.GetType().GetMethod("bar", new Type[] { typeof(Int32) });            mi.Invoke(f, new object[] { arg });            mi = f.GetType().GetMethod("bar", new Type[] { typeof(Int32).MakeByRefType() });            mi.Invoke(f, new object[] { refArg });            mi = f.GetType().GetMethod("bar", new Type[] { typeof(Int32).MakeArrayType() });            mi.Invoke(f, new object[] { argArray });            return 0;        }    }}

By the way, Type.MakeByRefType(), Type.MakeArrayType() and Type.MakePointerType() are not supported in the .net Compact Framework (yet?).  However, Type.MakeGenericType() is supported.