Covariance, Contravariance and Invariance
来源:互联网 发布:java流程开发工具 编辑:程序博客网 时间:2024/05/18 06:21
Have a look at this article for an explanation of Covariance and Contravariance.
http://msdn.microsoft.com/en-us/library/dd799517.aspx
The CLR already had some support for variance in generic types and with c# 4 comes the syntax to use this. With generic variance the variance is applied to the type parameters of the interfaces and delegate types.
Covariance is about being able to treat a returned value as a more general type, and is possible when the interface method(s) only return that type. In this example the derived interface instance can be reassigned as the base, but not the other way around.
public interface ISomeInterfaceWithOut<out T> { T GetSomething(); } ISomeInterfaceWithOut<Apple> b = new Blah<Apple>(); ISomeInterfaceWithOut<Fruit> fruit = b;
Contravariance is about being able to treat a parameter type as a more specific type, and is possible when the interface method(s) only consume that type. In this example the base interface instance can be reassigned as the derived, but not the other way around.
public interface ISomeInterfaceWithIn<in T> { void SetSomething(T instance); } ISomeInterfaceWithIn<Fruit> b = new Blah<Fruit>(); ISomeInterfaceWithIn<Apple> apple = b;
Invariance is when the both cases are happening and the interface method(s) are both returning and consuming the type. Neither covariance or contravariance can apply. Here any usage like the above will not work, as the 'out T' covariance or 'in T' contravariance type parameter is not allowed to be defined as the methods contain both cases.
Consider this:
//it is not possible to declare 'out T' or 'in T' here - invalid variance public interface ISomeInterface<T> { T GetSomething(); void SetSomething(T instance); }
Neither of your examples will work as they are. Contravariance/covariance applies to interfaces and delegates which have had their generic type declared as 'in' / 'out', IList is invariant.
Since the IEnumerable<T>
interface is covariant from .NET 4, you can do this from 4 onwards but not 3.5. Using fruits as IList here will not work when declaring fruits - it is not covariant.
List<Apple> apples = new List<Apple>(); //List<Apple> apples implements IEnumerable<Apple> IEnumerable<Fruit> fruits = apples;
Here is the definition of IEnumerable<T>
//Version=4.0.0.0 public interface IEnumerable<out T> : IEnumerable { new IEnumerator<T> GetEnumerator(); } //Version=2.0.0.0 public interface IEnumerable<T> : IEnumerable { new IEnumerator<T> GetEnumerator(); }
- Covariance, Contravariance and Invariance
- Invariance, covariance and contravariance
- Covariance and Contravariance
- Covariance and Contravariance in Java
- 协变(covariance),逆变(contravariance)与不变(invariance)
- .Net 2.0 新功能:委托中的协变与逆变(Covariance and Contravariance in Delegates)
- Covariance and Contravariance in Generics(泛型中的协变和逆变)
- 对协变和逆变的理解(Contravariance and Covariance)
- .NET 4.0 “Covariance”和“Contravariance”趣话
- .NET 4.0 “Covariance”和“Contravariance”趣话
- 协变(Covariance)与逆变(Contravariance)
- Covariance and Contra-variance
- contravariance
- Delegate(委托)中的Covariance(协变)和Contravariance(逆变)
- Covariance Matrices and Data Distributions
- Mean Vector and Covariance Matrix
- covariance
- Covariance
- 自定义NavigationBar的背景(兼容ios4)
- Android开发:什么是IBinder
- Java异常处理
- 锂电池及其充电电路漫谈
- 将Page_Load放在aspx页面
- Covariance, Contravariance and Invariance
- Android访问外部DB文件
- Android中的Parcel是什么
- IE6下支持li:hover的鼠标滑过效果,方法绝对正确,我已测试过
- 问题小结(12)-让文字颜色随焦点变化
- .Net那点事儿系列:C#操作Xml:通过XmlDocument读写Xml文档
- sprintf()函数
- 7z介绍、7z命令在linux的安装和使用、7z移植到嵌入式linux的系列专题汇总
- asp.net 调用远程webservice(手机归属地查询)