泛型的可变性分析
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace GenericTest
8 {
9 class Program
10 {
11 /// <summary>
12 ///
13 /// </summary>
14 /// <param name="args"></param>
15 static void Main(string[] args)
16 {
17
18 }
19
20 /// <summary>
21 /// 泛型协变和逆变的代码示例
22 /// 用最简单的代码解释问题
23 /// 协变 和 逆变 其实过程基本一致 本示例使用委托 一下都是针对委托
24 /// 1:声明源方法,委托实例化 用Source表示
25 /// 2:声明目标用Destination 指向 Source
26 /// 3:调用!!!重要 如果不调用 就不能彻底的理解 泛型的可变性
27 /// 所有的转变都发生在调用的时候,通过分析调用过程能够理解泛型的可变性
28 ///
29 /// 通过以上步骤,分析具体代码加强泛型可变性的理解
30 /// </summary>
31 public static void GenericVariant()
32 {
33 //协变
34 //声明源方法,委托实例化 用Source表示
35 Func<string> funcSource = () => "generic variant";
36 //声明目标用Destination表示 并进行委托转换 Source->Destination
37 Func<object> funcDestination = funcSource;
38
39 //调用
40 //调用过程 实际是调用了 funcSource 返回了 string 值
41 //变变变 发生在 从String 的返回值 转换成了Object
42 //注意 out 参数转变方向是 Source -> Destination
43 object result = funcDestination();
44 //string result = funcDestination();
45
46 //逆变
47 //声明源方法,委托实例化 用Source表示 输入参数为object
48 Action<object> actionSource = arg => { Console.Write(arg.ToString()); };
49 //声明目标用Destination表示 并进行委托转换 Source->Destination
50 Action<string> actionDestination = actionSource;
51 //调用
52 //变变变 发生在 从String 的输入参数 转换成了Object
53 //调用过程 实际是调用了 funcSource 返回了 输入参数为object 值
54 //注意 in参数转变方向是 Destination -> Source
55 //actionDestination(new object());
56 actionDestination("abc");
57 /*
58 out 针对返回值 所以 转变方向为 source => destination
59 in 针对输入参数,所以转变方向为 destination =>source
60 其实 协变、逆变都是类型安全的转变
61 */
62
63 }
64 }
65 }