看到过园子里面几篇协变和逆变的文章,但是总觉得写得不够清晰,文章这东西最重要的是要把自己想表达的观点表达出来,这个过程应该是把复杂的东西消化出来从而简单化,清晰化,而不是故弄玄虚,反其道而行之,下面我们言归正传啦。
我们先来看一段MSDN原文给协变,逆变和变体下个定义:
A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant. Both C# and Visual Basic enable you to create your own variant interfaces and delegates.
如果泛型接口或委托的泛型参数声明为协变或逆变,则将该泛型接口或委托称为“变体”。 C# 和 Visual Basic 都允许您创建自己的变体接口和委托。
通俗解释:
变体定义 - 带有协变或逆变参数的泛型接口或委托。也就是说协变和逆变主要关注点在泛型接口或委托。
那什么又是协变和逆变呢?
协变
我们先来看下面一个来自MSDN的例子:
// 协变
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
//大家看到了么一个声明为IEnumerable<string>的接口类型被赋给了一个更低级别的IEnumerable<object>.
//对,这就是协变。再来看一个例子:
class Base
{
public static void PrintBases(IEnumerable<Base> bases)
{
foreach(Base b in bases)
{
Console.WriteLine(b);
}
}
}
class Derived : Base
{
public static void Main()
{
List<Derived> dlist = new List<Derived>();
Derived.PrintBases(dlist);
//由于IEnumerable<T>接口是协变的,所以PrintBases(IEnumerable<Base> bases)
//可以接收一个更加具体化的IEnumerable<Derived>作为其参数。
IEnumerable<Base> bIEnum = dlist;
}
}
下面给协变下个定义:
协变:让一个带有协变参数的泛型接口(或委托)可以接收类型更加精细化,具体化的泛型接口(或委托)作为参数,可以看成OO中多态的一个延伸。
逆变
// 逆变
// Assume that the following method is in the class:
// static void SetObject(object o) { }
Action<object> actObject = SetObject;
Action<string> actString = actObject;
//委托actString中以后要使用更加精细化的类型string不能再使用object啦!
string strHello(“Hello”);
actString(strHello);
大家看到了么?一个声明为Action<object>的类型被赋给了一个Action<string>,大家都知道,Action<T>接收参数,没有返回值,所以其中的object和string是其参数,这个过程其实就是参数的约束更加强了,也就是说让参数类型更加精细化。下面我们来给逆变下个定义:
逆变:让一个带有协变参数的泛型接口(或委托)可以接收粒度更粗的泛型接口或委托作为参数,这个过程实际上是参数类型更加精细化的过程。
总结
一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值);逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确。
通常,协变类型参数可用作委托的返回类型,而逆变类型参数可用作参数类型。对于接口,协变类型参数可用作接口的方法的返回类型,而逆变类型参数可用作接口的方法的参数类型。
分享到:
相关推荐
协变和逆变都是泛型类型系统的一部分,主要用来解决泛型类型之间的继承关系和类型转换问题。 协变(Covariant) 协变是指泛型类型参数可以被隐式地转换为其基类型的能力。这意味着,如果我们有一个泛型类型参数 T...
.NET 4.0引入了对泛型协变(covariance)和反变(contravariance)的支持,这是在编程语言C#和VB中的一项重要改进。协变和反变是类型系统中的概念,它们允许在特定条件下,类型之间的转换变得更加灵活,从而提高代码...
本文将基于给定的“tensors paper”文件内容,深入探讨张量的基础知识,特别是关于逆变(Contravariant)和协变(Covariant)向量的概念。 ### 张量的引言 由Joakim Strandberg在2005年撰写的《张量介绍》一文,...
【摘要】:这篇论文提出了一种新的神经网络架构——协变组合网络(Covariant Compositional Networks,简称CCNs),用于学习图结构数据。传统方法通常通过消息传递机制处理图的不变性问题,其中每个节点聚合来自邻居...
首先,局部协变场理论(Locally Covariant Field Theory)是量子场论中的一个重要框架,尤其是在弯曲时空(curved spacetimes)的背景下。在此框架下,物理定律可以保证在不同点的局部都是相同的,因此理论具有局部...
在图像处理和计算机视觉领域,Affine Covariant Features是一种重要的图像特征检测方法。这些特性具有在仿射变换下保持不变的性质,使得它们在多视角和几何形变的环境中非常有用。"affine-covariant-features.tar.gz...
协变返回类型和智能指针 协变返回类型是一种语言功能,它允许您将虚函数的返回类型更改为协变类型,即。 指向派生类的指针而不是指向基类的指针 - 请参见下面的示例: struct Figure { virtual ~Figure () = ...
1. 协变密度泛函理论(Covariant density functional theory):这是一种在物理学中用于描述核物质性质的理论模型,它利用相对论的协变性原理结合密度泛函理论。在核物理中,密度泛函理论基于核子密度分布来计算核...
资料内容:牛津大学经典图像匹配评估数据集、Affine Covariant Regions Datasets、数据集文件内容主要包含Bikes(模糊变化)、Trees(模糊变化)、Graffiti(视角变化)、Wall(视角变化)、Leuven(光照变化)、UBC...
在解释器方面,Covariant Script提供了一个标准的解释器,用于执行语言的语句和表达式。该解释器支持语句的解析、语法分析、语义分析等阶段。 在API方面,Covariant Script提供了一个标准库,包括全局、异常、输入...
- 协变和逆变:类型参数可以标记为协变covariant(+T)或逆变contravariant(-T),影响类型参数在多态中的行为。 - Existential Types:用于处理类型参数的“存在”信息,通常在类型系统复杂的情况下使用。 掌握...
10. **协变与逆变**:在泛型中,我们还可以讨论协变(covariant)和逆变(contravariant)的概念。简单来说,如果子类型可以赋值给父类型,那么这种关系在泛型中被称为协变;反之,如果父类型可以赋值给子类型,那么...
C / C ++本机接口(CNI)系统:从C / C ++和协变脚本转换翻译调用 解释器引导程序:一种从C ++访问Covariant脚本运行时的便携式方法 CNI Composer Macro:将扩展系统和CNI系统有机地结合在一起 自主研发的高效编译...
【标题】:“js代码-[机密]协变面试问题:函数式练习(JavaScript)” 【描述】:这个压缩包文件包含了一个与JavaScript相关的面试题目,它着重于函数式编程的概念和技巧。"Covariant Interview Question"可能指的...
matlab特征点代码学习判别和变换协变局部特征检测器 该代码是我们CVPR 2017论文的培训和评估代码。 它包括翻译协变局部特征检测器的实现。 仿射协方差模型将在将来添加。 @inproceedings {zhang2017learning,标题= ...
Covariant Script编程语言,简称CovScript,是一款专为多领域应用而设计的开源、开放源代码的动态强类型编程语言。它以其强大的功能和灵活性,在数据分析、可视化以及系统软件开发等方面展现了广泛的应用潜力。 在...
在本小测试中,我们将探讨几个与Java泛型相关的概念:通配符(Wildcards)、消除(Erasure)、协变(Covariance)和原始类型(Raw Types)。以下是对这些概念的详细解释: 1. **通配符(Wildcards)** - 通配符是...
基于协变密度泛函理论对核物质对称能的同位旋耦合道分解,赵前,孙保元,基于协变密度泛函理论,对势能密度泛函进行同位旋耦合道分解,研究了其随同位旋与密度的依赖性质以及对与核物质对称能的相关影响。�
CovScript 是一种动态类型的脚本语言,强调简洁和高效,支持泛型、协变和逆变等高级特性。cspkg 的设计理念是与CovScript语言特性相辅相成,为开发者提供一套完整的生态系统,使得代码的组织和依赖管理更加有序。 *...