2010-05-13 75 views
1

安裝後,我有幾個通用函數,並且需要在運行時選擇由兩個字符串標識的類型和函數。在運行時指定通用委託類型參數

我第一次嘗試是這樣的:

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這樣的函數的數量會增加很多數字,所以我不想嵌套開關。

那麼我怎樣才能使這個工作不使用嵌套開關?

回答

4

您需要使用反思:

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); 
+0

'typeof運算(FOOBAR).GetMethod( 「富」,BindingFlags.Static);'總是給我返回null,任何線索,爲什麼? (我會看看msdn文檔的GetMethod(),但像往常一樣,我只能得到一個「對不起,我們無法爲您的請求服務。」) – smerlin 2010-05-13 13:40:08

+0

好吧,我需要一個額外的'BindingFlags.Public',但MakeGenericMethod返回:: void foo(Int32)不是GenericMethodDefinition。 MakeGenericMethod只能在MethodBase.IsGenericMethodDefinition爲true的方法上調用。 – smerlin 2010-05-13 13:55:13

+0

nvm,得到它的工作(我的foo/bar方法之一戰爭不通用,導致該錯誤)。 – smerlin 2010-05-13 14:21:05