t8.gs,吉林妈咪宝贝网,高考总分是多少2017
从c# 4.0开始,泛型接口和泛型委托都支持协变和逆变,由于历史原因,数组也支持协变。
里氏替换原则:任何基类可以出现的地方,子类一定可以出现。
协变(out)
abstract class animal {} class dog : animal {} class cat : animal {} interface ipoppable<t> { t pop(); } class mystack<t> : ipoppable<t> { private int _pos; private readonly t[] _data = new t[100]; public void push(t obj) => _data[_pos++] = obj; public t pop() => _data[--_pos]; }
以下代码是无法通过编译的
var dogs = new mystack<dog>(); ipoppable<animal> animals1 = dogs; // 此处会发生编译错误 stack<animal> animals2 = dogs; // 此处会发生编译错误
此时,我们如果需要为动物园饲养员新增一个输入参数为stack<animal>饲喂的方法,一个比较好的方法是新增一个约束泛型方法:
class zookeeper { public static void feed<t>(ipoppable<t> animals) where t : animal {} } // 或者 class zookeeper { public static void feed<t>(stack<t> animals) where t : animal {} } // main zookeeper.feed(dogs);
现在,c#增加了协变
使ipoppable<t>接口支持协变
// 仅仅增加了一个 out 声明 interface ipoppable<out t> { t pop(); }
简化feed方法
class zookeeper { public static void feed(ipoppable<animal> animals) {} } // main zookeeper.feed(dogs);
协变的天然特性——仅可作为方法返回值,接口(或委托)外部无法进行元素添加,确保了泛型类型安全性,所以不用担心dog的集合中出现cat
常用的支持协变的接口和委托有:
ienumerable<dog> dogs = enumerable.empty<dog>(); ienumerable<animal> animals = dogs; var doglist = new list<dog>(); ienumerable<animal> animals = doglist;
另外,由于历史原因,数组也支持协变,例如
var dogs = new dog[10]; animal[] animals = dogs;
但是无法保证类型安全性,以下代码可正常进行编译,但是运行时会报错
animals[0] = new cat(); // 运行时会报错
逆变(in)
abstract class animal {} class dog : animal {} class cat : animal {} interface ipushable<in t> { void push(t obj); } class mystack<t> : ipushable<t> { private int _pos; private readonly t[] _data = new t[100]; public void push(t obj) => _data[_pos++] = obj; public t pop() => _data[--_pos]; } // main var animals = new mystack<animal>(); animals.push(new cat()); ipushable<dog> dogs = animals; dogs.push(new dog());
逆变的天然特性——仅可作为方法输入参数,接口(或委托)无法进行元素获取,即只能将子类赋值到父类上,进而保证了类型安全性。
另外,常用支持逆变的接口和委托有:
action<animal> animalaction = new action<animal>(a => { }); action<dog> dogaction = animalaction;
到此这篇关于你了解c#的协变和逆变吗,看完这篇就懂了的文章就介绍到这了,更多相关c# 协变逆变内容请搜索移动技术网以前的文章或继续浏览下面的相关文章希望大家以后多多支持移动技术网!
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
C#实现获取本地内网(局域网)和外网(公网)IP地址的方法分析
浅谈Visual Studio 2019 Vue项目的目录结构
Visual Studio 2019配置vue项目的图文教程详解
网友评论