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.


Comments (0)

Skip to main content