Covariance and Contravariance (C#)

https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/concepts/covariance-contravariance/

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 type IEnumerable<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 type IEnumerable<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 type IEnumerable<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#)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 协变(covariance),逆变(contravariance)与不变(invariance)

    协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...

  4. C#(转自wiki)

    C#是微软推出的一种基于.NET框架的.面向对象的高级编程语言.C#的发音为"C sharp",模仿音乐上的音名"C♯"(C调升),是C语言的升级的意思.其正确 ...

  5. C#的变迁史 - C# 4.0篇

    C# 4.0 (.NET 4.0, VS2010) 第四代C#借鉴了动态语言的特性,搞出了动态语言运行时,真的是全面向“高大上”靠齐啊. 1. DLR动态语言运行时 C#作为静态语言,它需要编译以后运 ...

  6. Adaptive Code Via C#读书笔记

    原书链接: http://www.amazon.com/Adaptive-Code-via-principles-Developer-ebook/dp/B00OCLLYTY/ref=dp_kinw_s ...

  7. Nemerle Quick Guide

    This is a quick guide covering nearly all of Nemerle's features. It should be especially useful to a ...

  8. [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望

    发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...

  9. 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 ...

随机推荐

  1. Cookies Client Identification

    HTTP The Definitive Guide Cookies are the best current way to identify users and allow persistent se ...

  2. 未安装git lfs导致git下载不完整,没有错误提示

    git clone命令没有报错. --recursive选项也加上了. cmake命令没有报错 make命令出错. 最后发现是因为没有安装git lfs,导致大文件下载不完整.最坑的是下载的时候也没有 ...

  3. 修改计算机名后SQLServer无法使用windows账号登录

    USE master     GO    EXEC sp_configure'allow updates',1 RECONFIGURE WITH OVERRIDE   -- 设置两个变量    DEC ...

  4. Android在使用WebView时,通过Javascript调用JAVA函数

    webView = (WebView) findViewById(R.id.article_webview); //WebView启用Javascript脚本运行 webView.getSetting ...

  5. 20165324 Java实验四 Android程序设计

    20165324 Java实验四 Android程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年5月1 ...

  6. Deep learning与Neural Network

    深度学习是机器学习研究中的一个新的领域,其动机在于建立.模拟人脑进行分析学习的神经网络,它模仿人脑的机制来解释数据,例如图像,声音和文本.深度学习是无监督学习的一种. 深度学习的概念源于人工神经网络的 ...

  7. docker——端口映射与容器互联

    在生产环境中,单个服务往往是独立的,但是服务与服务之间往往是相互依赖的,这样对于容器来说,容器之间就需要相互访问.除了网络访问之外,docker还提供了另外两种方式来满足服务的访问. 一:允许映射容器 ...

  8. delphi 正则表达式

    常用正则表式 正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是个头疼的 ...

  9. delphi pchar 指针错误

    2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var P: Pchar; //P 是指针 CSize: Cardinal; ...

  10. javascript 理解对象--- 属性类型

    ECMA-262 把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数: var Person = { name:"wsc", age :"25", ...