[C#]浅谈协变与逆变

 

 

 

 

 

 

 

 

 

说白了,就是为了让泛型也能搞工厂模式。   

 

显然第二行的object到string是非类型安全的,那为什么第四行的object到string就是类型安全的呢?
结合上一个方法体的示例,来看这段代码:

复制代码
1 Action<List<int>> myAction = new Action<IList<int>>(
2     (list) =>
3     {
4         Console.WriteLine(list.Count);
5     });
6 myAction(new List<int> {1, 2, 3});
复制代码

第一行貌似是把IList转换成了List,但是实际上是这样的:
第六行传入的实参是一个List,进入方法体,List被转换成了IList,然后使用了IList的Count属性。
所以传参的时候其实发生的是派生类到基类的转换,自然也就是类型安全的了。

List<string>到IEnumerable<object>的协变其实也是类似的过程:

复制代码
 1 IEnumerable<Delegate> myEnumerable = new List<Action>
 2 {
 3     new Action(()=>Console.WriteLine(1)),
 4     new Action(()=>Console.WriteLine(2)),
 5     new Action(()=>Console.WriteLine(3)),
 6 };
 7 foreach (Delegate dlgt in myEnumerable)
 8 {
 9     dlgt.DynamicInvoke();
10 }
复制代码

实参是三个Action,调用的是Delegate的DynamicInvoke方法,完全的类型安全转换。

 

最后想说的是,所有死记硬背来的知识,都远远不如充分理解的知识来得可靠。

posted on 2019-11-28 10:51  shoutcharter  阅读(161)  评论(0编辑  收藏  举报

导航