重学c#系列——逆变和协变[二十四]


正文

什么是逆变和协变呢?

首先逆变和协变都是术语。

协变表示能够使用比原始指定的派生类型的派生程度更大的类型。

逆变表示能够使用比原始指定的派生类型的派生程度更小的类型。

这里student 继承 person。

这里这个报错合情合理。

这里可能有些刚入门的人认为,person 不是 student 的父类啊,为什么不可以呢?

一个列表student 同样也是一个列表的 person啊。

这可能是初学者的一个疑问。

但是实际情况是list<person> 是一个类型, list<student> 是一个类型。

所以他们无法隐式转换是正常的。

但是这样写就可以:

static void Main(string[] args)
{
	IEnumerable<Student> students = new List<Student>();
	IEnumerable<Person> peoples = students;
}
这样写没有报错,理论上IEnumerable<Student>是一种类型,IEnumerable<Person>是一种类型,不应该能隐私转换啊。

为什么呢?因为支持协变。

协变表示能够使用比原始指定的派生类型的派生程度更大的类型。

他们的结构如上。因为student是person的派生类,IEnumerable<T>原始指定了student,派生程度更大的类型是person,所以IEnumerable<Student>到IEnumerable<Person>符合协变。

协变怎么声明呢:

public interface IEnumerable<out T> : IEnumerable
{
	//
	// 摘要:
	//     Returns an enumerator that iterates through the collection.
	//
	// 返回结果:
	//     An enumerator that can be used to iterate through the collection.
	new IEnumerator<T> GetEnumerator();
}

C# 复制 全屏

这里协变有个特点,那就是协变参数T,只能用于返回类型。

原因是在运行时候还是new List<Student>(),返回自然是Student,那么student 可以赋值给person,这没问题。

那么协变参数T,不能用于参数呢? 是这样的。

本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;

2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;

3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;

4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;

5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/293453.html

(0)
上一篇 2022年11月24日
下一篇 2022年11月24日

相关推荐

发表回复

登录后才能评论