2011-01-19 70 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,所以它再次没有关系。

相关问题