Skip to main content
 首页 » 编程设计

c#之在运行时指定通用委托(delegate)类型参数

2024年02月24日20lyj

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

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

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 开关内嵌套了一个 methodstr 开关,反之亦然),但该解决方案非常丑陋且无法维护。

类型的数量几乎是固定的,但是像 foobar 这样的函数数量会增加很多,所以我不想要嵌套开关。

那么我怎样才能在不使用嵌套开关的情况下使它工作呢?

请您参考如下方法:

你需要使用反射:

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

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

Action<int> del = Delegate.CreateDelegate(typeof(Action<int>), null, genericMethod); 
 
for(int i=0; i<1000; ++i) 
    del(i);