views:

198

answers:

2

following setup, i have several generic functions, and i need to choose the type and the function identified by two strings at runtime.

my first try looked like this:

public static class FOOBAR
{
    public delegate void MyDelegateType(int param);

    public static void foo<T>(int param){...}
    public static void bar<T>(int param){...}

    public static void someMethod(string methodstr, string typestr)
    {
        MyDelegateType mydel;
        Type mytype;
        switch(typestr)
        {
            case "int": mytype = typeof(int); 
                        break;
            case "double": mytype = typeof(double); 
                           break;
            default: throw new InvalidTypeException(typestr);
        }
        switch(methodstr)
        {
            case "foo": mydel = foo<mytype>; //error
                        break;
            case "bar": mydel = bar<mytype>; //error
                        break;
            default: throw new InvalidTypeException(methodstr);
        }
        for(int i=0; i<1000; ++i)
            mydel(i);
    }
}

since this didnt work, i nested those switchs (a methodstr switch inside the typestr switch or viceversa), but that solution is really ugly and unmaintainable.

The number of types is pretty much fixed, but the number of functions like foo or bar will increase by high numbers, so i dont want nested switchs.

So how can i make this working without using nested switchs ?

A: 

Look at the documentation for Delegate.CreateDelegate

leppie
+1  A: 

You need to use Reflection:

MethodInfo method = typeof(FooBar).GetMethod(methodStr, BindingFlags.Static);
Type genericParam = Type.Parse(typestr);

MethodInfo genericMethod = method.MakeGenericMethod(genericParam);

for(int i=0; i<1000; ++i)
    genericMethod.Invoke(null, new object[] { i });

If the (non-generic) signature of the method will always be the same, it will be faster to create a delegate, like this:

Action<int> del = Delegate.CreateDelegate(typeof(Action<int>), null, genericMethod);

for(int i=0; i<1000; ++i)
    del(i);
SLaks
`typeof(FOOBAR).GetMethod("foo", BindingFlags.Static);` always returns null for me, any clue why ? (i would have looked at the msdn documentation for GetMethod(), but like always i only get a "Sorry, we were unable to service your request.")
smerlin
ok, i needed a additional `BindingFlags.Public`, but MakeGenericMethod returned:: void foo(Int32) is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
smerlin
nvm, got it working (one of my foo/bar methods war not generic, which caused that error).
smerlin