今天看到hbb0b0的一个帖子:如何用反射实现如下的泛型方法调用? , 询问如何获取一个重载的泛型方法。
因为Type没有提供GetGenericMethod方法,调用GetMethod可能会抛出一个AmbiguousMatchException异常或者无法获得正确的泛型方法。
本文提供一种途径,通过查询Type所有的Method找到正确的方法。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Reflection;
6
7 namespace Com.Colobu.Demo
8 {
9 class Program
10 {
11 static void Main( string [] args)
12 {
13 Demo < string > demo = new Demo < string > ();
14 InvokeMethods(demo);
15 Console.WriteLine( " ================================== " );
16 InvokeMethodsByReflect(demo);
17
18 Console.Read();
19 }
20
21 static void InvokeMethods(Demo < string > demo)
22 {
23 demo.MethodA( 1 );
24 demo.MethodA();
25 demo.MethodA( " hello " );
26 demo.MethodA < int > ( 4 );
27 demo.MethodA < int , long > ( 5 );
28 }
29
30
31 static void InvokeMethodsByReflect(Demo < string > demo)
32 {
33 Type demoType = demo.GetType();
34
35 // the below throw an AmbiguousMatchException
36 // MethodInfo mi = demoType.GetMethod("MethodA");
37
38 MethodInfo mi = demoType.GetMethod( " MethodA " , new Type[] { typeof ( int ) } ); // get the 1st method
39 mi.Invoke(demo, new object [] { 1 } );
40
41 mi = demoType.GetMethod( " MethodA " , new Type[] {} ); // get the 2nd method
42 mi.Invoke(demo, null );
43
44 mi = demoType.GetMethod( " MethodA " , new Type[] { typeof ( string ) } ); // get the 3rd method
45 mi.Invoke(demo, new object [] { " hello " } );
46
47 mi = demoType.GetMethods().First(m => m.Name.Equals( " MethodA " ) && m.IsGenericMethod && m.GetGenericArguments().Length == 1 );
48 mi.MakeGenericMethod( typeof ( int )).Invoke(demo, new object [] { 4 } );
49
50 mi = demoType.GetMethods().First(m => m.Name.Equals( " MethodA " ) && m.IsGenericMethod && m.GetGenericArguments().Length == 2 );
51 mi.MakeGenericMethod( typeof ( int ), typeof ( long )).Invoke(demo, new object [] { 5 } );
52
53
54 }
55
56
57 }
58
59 class Demo < U >
60 {
61 public void MethodA( int arg)
62 {
63 Console.WriteLine( " 1: " + arg.ToString());
64 }
65
66 public void MethodA()
67 {
68
69 Console.WriteLine( " 2:null " );
70 }
71
72 public void MethodA(U arg)
73 {
74 Console.WriteLine( " 3: " + arg.ToString());
75 }
76
77 public void MethodA < T > (T arg)
78 {
79 Console.WriteLine( " 4: " + arg.ToString());
80 }
81
82 public void MethodA < T,S > (T arg)
83 {
84 Console.WriteLine( " 5: " + arg.ToString());
85 }
86
87 }
88
89 }