在 Net7.0环境下通过反射创建泛型实例和调用泛型方法

发布时间 2023-09-20 11:17:01作者: 可均可可

一、介绍
    最近没事干,就用闲暇时间写点东西,也记录一下温习历程。老人说的好,好记性,不如烂笔头。时间一长,当时记忆的再清楚,都会变得模糊,索性就写博客记录下来,如果下次需要,直接打开博客就找到了,不用去网上乱找了。
    今天我要写一些有关反射和泛型的关系,泛型的类型的创建和泛型方法的调用是普通类型(非泛型类型)的创建和调用还是有区别的,如果不知道,肯定会憋出一身臭汗,其实知道了,也没什么。怕时间长了,忘记。就把关键的代码写出来,为自己提个醒。
    测试环境说明:
          操作系统:Windows10 Professinal
          开发工具:Visual Studio 2022
          测试平台:Windows Console Application
          框架平台:Net 7.0
          
二、我的代码
    我的测试很简单,分为两种,一种是泛型类型的创建和实例化,第二种是泛型方法的调用。当然了,泛型方法的调用,也区分为:泛型类型的泛型方法的调用和非泛型类型的泛型方法的调用,废话不多说,直接上代码。
    当然有泛型的创建使用,还有其他类型的访问,把所有情况都包好了。
    辅助类型:    

 1     /// <summary>
 2     /// 非泛型类型的泛型方法反射调用。
 3     /// </summary>
 4     internal class InstanceGenericMethod
 5     {
 6         /// <summary>
 7         /// 泛型方法不是生成占位符。
 8         /// </summary>
 9         /// <typeparam name="T"></typeparam>
10         /// <typeparam name="S"></typeparam>
11         /// <param name="parameter"></param>
12         /// <param name="s"></param>
13         /// <returns></returns>
14         public T Generate<T, S>(T parameter, S s)
15         {
16             Console.WriteLine("非泛型类-泛型方法:Generate<T, S>(T parameter, S s) 执行");
17             return parameter;
18         }
19     }
20 
21     /// <summary>
22     /// 泛型类型的泛型方法反射调用。
23     /// </summary>
24     /// <typeparam name="X"></typeparam>
25     internal class GenericClassMethod<X>
26     {
27         /// <summary>
28         /// 
29         /// </summary>
30         /// <typeparam name="T"></typeparam>
31         /// <typeparam name="S"></typeparam>
32         /// <param name="parameter"></param>
33         /// <param name="s"></param>
34         /// <returns></returns>
35         public X Generate<T, S>(X x, T t, S s)
36         {
37             Console.WriteLine("泛型类-泛型方法:Generate<T, S>(T parameter, S s) 执行");
38             return x;
39         }
40     }

    实例方法调用类型:

 1     /// <summary>
 2     /// 针对实例类型方法反射的调用,包含重载方法的反射调用。
 3     /// </summary>
 4     internal class InstanceMethod
 5     {
 6         /// <summary>
 7         /// 无参唯一实例方法。
 8         /// </summary>
 9         public void Process()
10         {
11             Console.WriteLine("Process()无参实例方法执行。");
12         }
13 
14         /// <summary>
15         /// 多参实例方法。
16         /// </summary>
17         /// <param name="age"></param>
18         /// <param name="name"></param>
19         /// <param name="dateTime"></param>
20         public void DoSomething(int age,string name,DateTime dateTime)
21         {
22             Console.WriteLine("DoSomething(int age,string name,DateTime dateTime)多参实例方法执行。");
23         }
24 
25         /// <summary>
26         /// 重载方法
27         /// </summary>
28         public void Generate()
29         {
30             Console.WriteLine($"Generate()");
31         }
32 
33         /// <summary>
34         /// 重载方法
35         /// </summary>
36         /// <param name="age"></param>
37         /// <param name="name"></param>
38         public void Generate(int age,string name)
39         {
40             Console.WriteLine($"Generate(int age,string name)");
41         }
42 
43         /// <summary>
44         /// 重载方法
45         /// </summary>
46         /// <param name="age"></param>
47         /// <param name="name"></param>
48         /// <param name="stream"></param>
49         public void Generate(int age, string name, Stream stream)
50         {
51             Console.WriteLine($"Generate(int age, string name, Stream stream)已执行");
52         }
53 
54         /// <summary>
55         /// 有返回值的重载方法
56         /// </summary>
57         /// <param name="age"></param>
58         /// <param name="name"></param>
59         /// <param name="stream"></param>
60         public decimal Generate(int age, string name, Stream stream,decimal money)
61         {
62             Console.WriteLine($" Generate(int age, string name, Stream stream,decimal money) 已执行");
63             return money;
64         }
65     }

    使用静态和实例方法反射调用的类型:

 1     /// <summary>
 2     /// 通过反射调用私有方法。
 3     /// </summary>
 4     internal class PrivateMethodDemo
 5     {
 6         /// <summary>
 7         /// 有参数的实例私有方法。
 8         /// </summary>
 9         /// <param name="age"></param>
10         /// <param name="name"></param>
11         private void PrivateInstanceMethodTest(int age, string name)
12         {
13             Console.WriteLine($"实例方法:年龄:{age};姓名:{name}");
14         }
15 
16         /// <summary>
17         /// 有参数的静态私有方法。
18         /// </summary>
19         /// <param name="age"></param>
20         /// <param name="name"></param>
21         private static void PrivateStaticMethodTest(int age, string name)
22         {
23             Console.WriteLine($"静态方法:年龄:{age};姓名:{name}");
24         }
25     }

    静态方法反射调用的类型:

 1     /// <summary>
 2     /// 静态方法反射调用,包含重载静态方法
 3     /// </summary>
 4     internal class StaticMethod
 5     {
 6         /// <summary>
 7         /// 
 8         /// </summary>
 9         public static void Process()
10         {
11             Console.WriteLine("Process()无参实例方法执行。");
12         }
13 
14         /// <summary>
15         /// 
16         /// </summary>
17         /// <param name="age"></param>
18         /// <param name="name"></param>
19         /// <param name="dateTime"></param>
20         public static void DoSomething(int age, string name, DateTime dateTime)
21         {
22             Console.WriteLine("DoSomething(int age,string name,DateTime dateTime)多参实例方法执行。");
23         }
24 
25         /// <summary>
26         /// 重载方法
27         /// </summary>
28         public static void Generate()
29         {
30             Console.WriteLine("重载方法:Generate() 方法执行。");
31         }
32 
33         /// <summary>
34         /// 重载方法
35         /// </summary>
36         /// <param name="age"></param>
37         /// <param name="name"></param>
38         public static void Generate(int age, string name)
39         {
40             Console.WriteLine("重载方法:Generate(int age, string name) 方法执行。");
41         }
42 
43         /// <summary>
44         /// 重载方法
45         /// </summary>
46         /// <param name="age"></param>
47         /// <param name="name"></param>
48         /// <param name="stream"></param>
49         public static void Generate(int age, string name, Stream stream)
50         {
51             Console.WriteLine("重载方法:Generate(int age, string name, Stream stream) 方法执行。");
52         }
53 
54         /// <summary>
55         /// 有返回值的重载方法
56         /// </summary>
57         /// <param name="age"></param>
58         /// <param name="name"></param>
59         /// <param name="stream"></param>
60         public static decimal Generate(int age, string name, Stream stream, decimal money)
61         {
62             Console.WriteLine("重载方法:Generate(int age, string name, Stream stream, decimal money) 方法执行。");
63             return money;
64         }
65     }

    反射调用重载构造函数的类型:

 1     /// <summary>
 2     /// 反射调用重载构造函数
 3     /// </summary>
 4     internal class MultiCtorDemo
 5     {
 6         private readonly string? name;
 7         private readonly DateTime dateTime;
 8         private readonly int age;
 9 
10         /// <summary>
11         /// 无参构造函数
12         /// </summary>
13         public MultiCtorDemo()
14         {
15             
16         }
17 
18         /// <summary>
19         /// 重载构造函数
20         /// </summary>
21         /// <param name="name"></param>
22         public MultiCtorDemo(string name)
23         {
24             this.name = name;
25         }
26 
27         /// <summary>
28         /// 重载构造函数
29         /// </summary>
30         /// <param name="age"></param>
31         public MultiCtorDemo(int age)
32         {
33             this.age = age;
34         }
35 
36         /// <summary>
37         /// 重载构造函数
38         /// </summary>
39         /// <param name="age"></param>
40         /// <param name="name"></param>
41         /// <param name="dateTime"></param>
42         public MultiCtorDemo(int age,string name,DateTime dateTime)
43         {
44             this.age = age;
45             this.name = name;
46             this.dateTime = dateTime;
47         }
48     }

    私有和受保护的构造函数反射调用的类型:

 1     /// <summary>
 2     /// 私有和受保护的构造函数反射调用
 3     /// </summary>
 4     internal class PrivateCtorDemo
 5     {
 6         private readonly int age;
 7 
 8         /// <summary>
 9         /// 私有构造函数
10         /// </summary>
11         private PrivateCtorDemo() { }
12 
13         /// <summary>
14         /// 受保护的构造函数
15         /// </summary>
16         /// <param name="age"></param>
17         protected PrivateCtorDemo(int age)
18         {
19             this.age = age;
20         }
21     }

    测试代码:    

  1             //202309181126、多构造函数反射调用
  2             {
  3                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
  4                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.MultiCtorDemo");
  5                 if (myType != null)
  6                 {
  7                     var instance = Activator.CreateInstance(myType);
  8                     var instance2 = Activator.CreateInstance(myType, new object[] { "刘雷" });
  9                     var instance3 = Activator.CreateInstance(myType, new object[] { 123 });
 10                     var instance4 = Activator.CreateInstance(myType, new object[] { 123, "黄飞虎", DateTime.Now });
 11                 }
 12             }
 13 
 14             //202309181135、私有构造函数反射调用(只有无参构造函数)
 15             {
 16                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
 17                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.PrivateCtorDemo");
 18                 if (myType != null)
 19                 {
 20                     var obj = Activator.CreateInstance(myType, true);
 21                 }
 22             }
 23 
 24             //202309181151、泛型类型的反射实例
 25             {
 26                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
 27                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.ReflectionGenericDemo`4");
 28                 if (myType != null)
 29                 {
 30                     var genericType = myType.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(float), typeof(decimal), });
 31                     var obj = Activator.CreateInstance(genericType);
 32                 }
 33             }
 34 
 35             //202309181309、实例方法反射调用
 36             {
 37                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
 38                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.InstanceMethod");
 39                 if (myType != null)
 40                 {
 41                     var myInstance = Activator.CreateInstance(myType);
 42                     if (myInstance != null)
 43                     {
 44                         var method = myType.GetMethod("Process");
 45                         method!.Invoke(myInstance, null);
 46 
 47                         var method2 = myType.GetMethod("DoSomething", new Type[] { typeof(int), typeof(string), typeof(DateTime) });
 48                         method2!.Invoke(myInstance, new object[] { 112233, "刘雷", DateTime.Now });
 49                     }
 50                 }
 51             }
 52 
 53             //202309181330、实例重载方法反射调用
 54             {
 55                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
 56                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.InstanceMethod");
 57                 if (myType != null)
 58                 {
 59                     var myInstance = Activator.CreateInstance(myType);
 60                     if (myInstance != null)
 61                     {
 62                         var method = myType.GetMethod("Generate", new Type[] { });
 63                         method!.Invoke(myInstance, null);
 64 
 65                         var method2 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string) });
 66                         method2!.Invoke(myInstance, new object[] { 112233, "刘雷" });
 67 
 68                         var method3 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream) });
 69                         method3!.Invoke(myInstance, new object[] { 112233, "刘雷", null });
 70 
 71                         var method4 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream), typeof(decimal) });
 72                         var value = method4!.Invoke(myInstance, new object[] { 112233, "刘雷", null, 4933m });
 73                         Console.WriteLine(value);
 74                     }
 75                 }
 76             }
 77 
 78             //202309181345、静态方法、重载方法反射调用(实例对象为空)
 79             {
 80                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
 81                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.StaticMethod");
 82                 if (myType != null)
 83                 {
 84                     var staticProcess = myType.GetMethod("Process");
 85                     staticProcess!.Invoke(null, null);
 86 
 87                     var staticDoSomething = myType.GetMethod("DoSomething", new Type[] { typeof(int), typeof(string), typeof(DateTime) });
 88                     staticDoSomething!.Invoke(null, new object[] { 123, "dddd", DateTime.Now });
 89 
 90                     var staticGenerate = myType.GetMethod("Generate", new Type[] { });
 91                     staticGenerate!.Invoke(null, null);
 92 
 93                     var staticGenerate2 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string) });
 94                     staticGenerate2!.Invoke(null, new object[] { 123, "123" });
 95 
 96                     var staticGenerate3 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream) });
 97                     staticGenerate3!.Invoke(null, new object[] { 123, "123", null });
 98 
 99                     var staticGenerate4 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream), typeof(decimal) });
100                     var value = staticGenerate4!.Invoke(null, new object[] { 123, "123", null, 2345m });
101                     Console.WriteLine(value);
102                 }
103             }
104 
105             //202309181345、静态方法、重载方法反射调用(实例对象不为空)
106             {
107                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
108                 var myType = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.StaticMethod");
109                 if (myType != null)
110                 {
111                     var instance = Activator.CreateInstance(myType);
112                     var staticProcess = myType.GetMethod("Process");
113                     staticProcess!.Invoke(instance, null);
114 
115                     var staticDoSomething = myType.GetMethod("DoSomething", new Type[] { typeof(int), typeof(string), typeof(DateTime) });
116                     staticDoSomething!.Invoke(instance, new object[] { 123, "dddd", DateTime.Now });
117 
118                     var staticGenerate = myType.GetMethod("Generate", new Type[] { });
119                     staticGenerate!.Invoke(instance, null);
120 
121                     var staticGenerate2 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string) });
122                     staticGenerate2!.Invoke(instance, new object[] { 123, "123" });
123 
124                     var staticGenerate3 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream) });
125                     staticGenerate3!.Invoke(instance, new object[] { 123, "123", null });
126 
127                     var staticGenerate4 = myType.GetMethod("Generate", new Type[] { typeof(int), typeof(string), typeof(Stream), typeof(decimal) });
128                     var value = staticGenerate4!.Invoke(instance, new object[] { 123, "123", null, 2345m });
129                     Console.WriteLine(value);
130                 }
131             }
132 
133             //202309181349、泛型方法反射调用
134             {
135                 //非泛型类型的泛型方法反射调用。
136                 {
137                     Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
138                     var type = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.InstanceGenericMethod");
139                     if (type != null)
140                     {
141                         var instance = Activator.CreateInstance(type);
142                         if (instance != null)
143                         {
144                             var method = type.GetMethod("Generate");
145                             var genericMethod = method!.MakeGenericMethod(typeof(int), typeof(string));
146                             var value = genericMethod.Invoke(instance, new object[] { 123, "魏延" });
147                             Console.WriteLine(value);
148                         }
149                     }
150                 }
151 
152                 //泛型类型的泛型方法反射调用。
153                 {
154                     Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
155                     var type = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.GenericClassMethod`1");
156                     if (type != null)
157                     {
158                         var genericType = type.MakeGenericType(new Type[] { typeof(int) });
159                         var instance = Activator.CreateInstance(genericType);
160                         if (instance != null)
161                         {
162                             var method = genericType.GetMethod("Generate");
163                             var genericMethod = method!.MakeGenericMethod(typeof(int), typeof(string));
164                             var value = genericMethod.Invoke(instance, new object[] { 123, 456, "魏延" });
165                             Console.WriteLine(value);
166                         }
167                     }
168                 }
169             }
170 
171             //202309191105、反射调用静态和实例私有方法
172             {
173                 Assembly assembly = Assembly.Load("PatrickLiu.DelegateDeep.AllStudy");
174                 var type = assembly.GetType("PatrickLiu.DelegateDeep.AllStudy.Reflections.Methods.PrivateMethodDemo");
175                 if (type != null)
176                 {
177                     var instance = Activator.CreateInstance(type);
178                     if (instance != null)
179                     {
180                         var privateInstanceMethod = type.GetMethod("PrivateInstanceMethodTest", BindingFlags.NonPublic|BindingFlags.Instance);
181                         privateInstanceMethod?.Invoke(instance,new object[] {123,"魏文长" });
182 
183                         var privateStaticMethod = type.GetMethod("PrivateStaticMethodTest", BindingFlags.NonPublic | BindingFlags.Static);
184                         privateStaticMethod?.Invoke(instance, new object[] { 123, "魏文长" });
185                     }
186                 }
187             }            


三、总结
    好了,写了不少了,其实这里不只是包含泛型类型,也包含其他的,私有方法的调用,静态方法的调用,重载方法和构造函数的调用,基本上都涉及到了,行了,以后有新的东西再写吧。每天努力一点点,老天不负有心人。