2011-01-19 68 views
2

如何調用SomeObject.SomeGenericInstanceMethod<T>(T arg)使用反射調用具有簽名的對象實例的泛型方法:SomeObject.SomeGenericInstanceMethod <T>(T參數)

有一些關於調用泛型方法的文章,但不太像這個。問題是方法參數參數被限制爲泛型參數。

我知道,如果簽名是不是

SomeObject.SomeGenericInstanceMethod<T>(string arg)

那麼我可以用

typeof (SomeObject).GetMethod("SomeGenericInstanceMethod", new Type[]{typeof (string)}).MakeGenericMethod(typeof(GenericParameter))

所以,我怎麼去獲取MethodInfo的時候經常得到的MethodInfo參數是一個泛型類型?謝謝!

另外,泛型參數可能有或沒有類型限制。

+0

[Select Right Generic Method with Reflection]的可能重複(http://stackoverflow.com/questions/3631547/select-right-generic-method-with-reflection) – nawfal 2014-01-17 15:22:17

回答

11

你這樣做的方式完全一樣。

當您調用MethodInfo.Invoke時,無論如何您都傳遞object[]中的所有參數,所以它不像您必須在編譯時知道類型。

樣品:

using System; 
using System.Reflection; 

class Test 
{ 
    public static void Foo<T>(T item) 
    { 
     Console.WriteLine("{0}: {1}", typeof(T), item); 
    } 

    static void CallByReflection(string name, Type typeArg, 
           object value) 
    { 
     // Just for simplicity, assume it's public etc 
     MethodInfo method = typeof(Test).GetMethod(name); 
     MethodInfo generic = method.MakeGenericMethod(typeArg); 
     generic.Invoke(null, new object[] { value }); 
    } 

    static void Main() 
    { 
     CallByReflection("Foo", typeof(object), "actually a string"); 
     CallByReflection("Foo", typeof(string), "still a string"); 
     // This would throw an exception 
     // CallByReflection("Foo", typeof(int), "oops"); 
    } 
} 
+2

如果存在多個重載名爲「名稱」的方法? – smartcaveman 2011-01-19 17:39:36

+1

@smartcaveman:不,你需要弄清楚哪一個可以打電話。當參數類型是通用的時,調用`GetMethod(string,Type [])`會變得非常棘手 - 我通常使用GetMethods和LINQ查詢來找到正確的方法。 – 2011-01-19 17:41:42

2

你這樣做完全一樣的方式,而是通過你的對象的實例:

typeof (SomeObject).GetMethod(
     "SomeGenericInstanceMethod", 
     yourObject.GetType()) 
       // Or typeof(TheClass), 
       // or typeof(T) if you're in a generic method 
    .MakeGenericMethod(typeof(GenericParameter)) 

MakeGenericMethod方法只需要您指定的泛型類型參數,而不是該方法的論點。

您將在稍後調用該方法時傳遞參數。然而,在這一點上,他們通過object,所以它再次沒有關係。

相關問題