Covariance and Contravariance (C#)
Covariance and Contravariance (C#)
In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments.
Covariance preserves assignment compatibility and contravariance reverses it.
The following code demonstrates the difference between assignment compatibility, covariance, and contravariance.
// Assignment compatibility.
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;
// Covariance.
IEnumerable<string> strings = new List<string>();
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;
// Contravariance.
// Assume that the following method is in the class:
// static void SetObject(object o) { }
Action<object> actObject = SetObject;
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;
public delegate void Action<in T>(T obj) Action的泛型委托,里面的T指定了是逆变的,本来的返回值类型是object的。现在范围缩小成string,不会影响程序的运行。
Covariance for arrays enables implicit conversion of an array of a more derived type to an array of a less derived type.
But this operation is not type safe, as shown in the following code example.
object[] array = new String[];
// The following statement produces a run-time exception.
// array[0] = 10;
Covariance and contravariance support for method groups allows for matching method signatures with delegate types.
This enables you to assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type.
For more information, see Variance in Delegates (C#) and Using Variance in Delegates (C#).
The following code example shows covariance and contravariance support for method groups.
static object GetObject() { return null; }
static void SetObject(object obj) { }
static string GetString() { return ""; }
static void SetString(string str) { }
static void Test()
{
// Covariance. A delegate specifies a return type as object,
// but you can assign a method that returns a string.
Func<object> del = GetString;
// Contravariance. A delegate specifies a parameter type as string,
// but you can assign a method that takes an object.
Action<string> del2 = SetObject;
}
In .NET Framework 4 or newer C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters.
For more information, see Variance in Generic Interfaces (C#) and Variance in Delegates (C#).
The following code example shows implicit reference conversion for generic interfaces.
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant.
C# enables you to create your own variant interfaces and delegates.
For more information, see Creating Variant Generic Interfaces (C#) and Variance in Delegates (C#).
Covariance and Contravariance in Generics
http://msdn.microsoft.com/en-us/library/dd799517.aspx
Covariance and contravariance are terms that refer to the ability to use a less derived (less specific) or more derived type (more specific) than originally specified.
Generic type parameters support covariance and contravariance to provide greater flexibility in assigning and using generic types.
When you are referring to a type system, covariance, contravariance, and invariance have the following definitions.
The examples assume a base class named Base and a derived class named Derived.
Covariance 协变Enables you to use a more derived type than originally specified.
You can assign an instance of
IEnumerable<Derived>(IEnumerable(Of Derived)in Visual Basic) to a variable of typeIEnumerable<Base>.Contravariance 逆变Enables you to use a more generic (less derived) type than originally specified.
You can assign an instance of
IEnumerable<Base>(IEnumerable(Of Base)in Visual Basic) to a variable of typeIEnumerable<Derived>.Invariance 不变性,恒定性Means that you can use only the type originally specified; so an invariant generic type parameter is neither covariant nor contravariant.
You cannot assign an instance of
IEnumerable<Base>(IEnumerable(Of Base)in Visual Basic) to a variable of typeIEnumerable<Derived>or vice versa.
Covariant type parameters enable you to make assignments that look much like ordinary Polymorphism, as shown in the following code.
Covariance and Contravariance (C#)的更多相关文章
- Covariance and Contravariance in C#, Part One
http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.a ...
- Covariance and Contravariance in C#, Part Two: Array Covariance
http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-a ...
- 协变(covariance),逆变(contravariance)与不变(invariance)
协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...
- C#(转自wiki)
C#是微软推出的一种基于.NET框架的.面向对象的高级编程语言.C#的发音为"C sharp",模仿音乐上的音名"C♯"(C调升),是C语言的升级的意思.其正确 ...
- C#的变迁史 - C# 4.0篇
C# 4.0 (.NET 4.0, VS2010) 第四代C#借鉴了动态语言的特性,搞出了动态语言运行时,真的是全面向“高大上”靠齐啊. 1. DLR动态语言运行时 C#作为静态语言,它需要编译以后运 ...
- Adaptive Code Via C#读书笔记
原书链接: http://www.amazon.com/Adaptive-Code-via-principles-Developer-ebook/dp/B00OCLLYTY/ref=dp_kinw_s ...
- Nemerle Quick Guide
This is a quick guide covering nearly all of Nemerle's features. It should be especially useful to a ...
- [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望
发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...
- Visual C#每一次新版本的变化
What's New in Visual C# .NET 2003[Visual Studio .NET 2003] What's New in Visual C# 2005 What's New i ...
随机推荐
- java generic super, extend
//Apple Orange 都继承自Fruit类,同时Jonathan是Apple的子类 List<? extends Fruit> list = new ArrayList< ...
- shell awk实战
一.文本处理 1.按行提取关键字频次(如取第5列) awk 'BEGIN{FS="|"} {a[$5]+=1;} END {for(i in a) print i ":& ...
- Celery(一个懂得 异步任务、定时任务、周期任务 的"芹菜")
一.什么是Celery? Celery 是基于Python实现的模块,用于执行异步.定时.周期任务的,其结构的组成是: - 用户任务 app - 管道 broker 用于存储任务(官方推荐 redis ...
- Android ListView工作原理完全解析(转自 郭霖老师博客)
原文地址:http://blog.csdn.net/guolin_blog/article/details/44996879 在Android所有常用的原生控件当中,用法最复杂的应该就是ListVie ...
- U盘安装CentOS7笔记
准备工具: 8G左右U盘; 最新版UltraISO; CentOS7光盘镜像; CentOS7的镜像文件可以在网易的开源镜像站或者阿里云的开源镜像站下载,地址分别是:http://mirrors.16 ...
- 宏表达式与函数、#undef、条件编译、
宏表达式在预编译期被处理,编译器不知道宏表达式的存在. 宏表达式没有任何的调用开销 宏表达式中不能出现递归定义. C语言中强大的内置宏 __FILE__:被编译的文件名 //双底线 __LINE__: ...
- 解析button和input type=”button”的区别
一.定义和用法 <button> 标签定义的是一个按钮. 在 button 元素内部,可以放置文本或图像.这是<button>与使用 input 元素创建的按钮的不同之处. 二 ...
- matplotlib对LaTeX数学公式的支持
Matlplotlib对LaTeX有一定的支持,如果记得使用raw字符串语法会很自然: xlabel(r"x2y4x2y4") 在matplotlib里面,可以使用LaTex的命令 ...
- Drools 规则引擎环境搭建
一.关于 drools 规则引擎 前面写过一篇 Drools 规则引擎相关的文章,这篇文章主要记录一下规则引擎的环境搭建和简单示例.不熟悉 drools 的朋友可以看看这篇文章: 自己写个 Drool ...
- 1-CommonJs
诞生背景JS没有模块系统.标准库较少.缺乏包管理工具:前端端没有模块化编程还可以,因为前端逻辑没那么复杂,可以工作下去,在服务器端逻辑性那么强必须要有模块为了让JS可以在任何地方运行,以达到Java. ...