代码之家  ›  专栏  ›  技术社区  ›  smerlin

在运行时指定泛型委托类型参数

  •  1
  • smerlin  · 技术社区  · 15 年前

    在设置之后,我有几个通用函数,我需要在运行时选择由两个字符串标识的类型和函数。

    我的第一次尝试是这样的:

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

    因为这不起作用,所以我嵌套了这些开关(typestr开关或viceversa中的methodstr开关),但是这个解决方案确实很难看,而且不可维护。

    类型的数量是固定的,但是函数的数量 foo bar 会增加很多,所以我不想要嵌套的开关。

    那么,我如何在不使用嵌套开关的情况下使其工作呢?

    2 回复  |  直到 14 年前
        1
  •  4
  •   SLaks    15 年前

    您需要使用反射:

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

    如果方法的(非泛型)签名始终相同,则创建委托会更快,如下所示:

    Action<int> del = Delegate.CreateDelegate(typeof(Action<int>), null, genericMethod);
    
    for(int i=0; i<1000; ++i)
        del(i);
    
        2
  •  0
  •   leppie    15 年前