c#中关于协变性和逆变性(又叫抗变)帮助理解
今天回忆了之前看的《深入理解C#》这本书中的泛型章节,其中对泛型的可变性的理解。泛型可变性分两种:协变和逆变。逆变也又称为抗变。
怎么理解这两个名词的意思:
①:协变即为在泛型接口类型中使用out标识的类型参数。协变的字面意思是“与变化的方向相同”②逆变那就是用in来标识的泛型接口类型的类型参数。逆变的字面意思是“与变化的方向相反”
需要注意的是无论是协变还是逆变也只能在泛型接口中来使用。
先来举个基本的例子,来加强你对可变性的理解。在C#中有隐式类型转换,比如:
string str = "nibian";
object str1 = str;
Console.WriteLine(str1);

大家都知道string类型是object类型的子类型,即string->object为子->父;从子类型到父类型的转换是隐式类型转换。
举个例子:
interface IDemo<out T>
{
T Method(string str);
}
class One : IDemo<string>
{
public string Method(string str)
{
return str;
}
}
class Two : IDemo<object>
{
public object Method(string str)
{
return str;
}
}
class Program
{
static void Main(string[] args)
{
IDemo<string> one = new One();
IDemo<object> two;
two = one;
Console.WriteLine(two.Method("2222"));
}
}
因为string是object类型的子类,在这里IDemo<string>和IDemo<object>类型之间也存在着类型转换的,从IDemo<string>向IDemo<object>进行的转换可以看成是子类型向父类型的隐式转换,它的这个用法就是协变。(这里必须要用out)
相反的我们在来看一下有关逆变的代码:
interface IDemo<in T>
{
string Method(T str);
}
class One : IDemo<string>
{
public string Method(string str)
{
return str;
}
}
class Two : IDemo<object>
{
public string Method(object str)
{
return str.ToString();
}
}
class Program
{
static void Main(string[] args)
{
IDemo<object> two = new Two();
IDemo<string> one;
one = two;
Console.WriteLine(one.Method("2222"));
}
}
同样的从IDemo<object>类型向IDemo<string>类型的转换,但是在这里我们却将父类型隐式转换为子类型的用法叫逆变。(这里必须要用in)
总结:协变和逆变就是在泛型接口类型将类型参数作为输入和输出的情况下,对类型间进行隐式转换的规律。
c#中关于协变性和逆变性(又叫抗变)帮助理解的更多相关文章
- JQuery选择器大全 前端面试送命题:面试题篇 对IOC和DI的通俗理解 c#中关于协变性和逆变性(又叫抗变)帮助理解
JQuery选择器大全 jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素 ...
- 不变性、协变性和逆变性(Invariance, Covariance & Contravariance)
源码下载 一.里氏替换原则(Liskov Substitution Principle LSP) 我们要讲的不是协变性和逆变性(Covariance & Contravariance)吗?是的 ...
- Java 泛型 协变性、逆变性
Java 泛型 协变性.逆变性 @author ixenos 摘要:协变性.协变通配符.协变数组.协变返回值 协变性.逆变性和无关性 在面向对象的计算机程序语言中,经常涉及到类型之间的转换,例如从具体 ...
- oc 的 协变性与逆变性
?协变性与逆变性是类型关系在范畴论的定义.是类型的继承关系在高阶类型中的定义? __kindof只是在统一继承体系下方便了类型转化,提供了使用时语法上的便捷:但是对于类型转换是否正确不做判定: kin ...
- C# 中的协变和逆变
作为一个从接触 Unity 3D 才开始学习 C# 的人,我一直只了解一些最基本.最简单的语言特性.最近看了<C# in Depth>这本书,发现这里面东西还真不少,即使除去和 Windo ...
- .NET泛型中的协变与逆变
泛型的可变性:协变性和逆变性 实质上,可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用. 我们已经习惯了普通继承中的可变性:例如,若某方法声明返回类型为Stream,在实现时可以返回一个M ...
- Java中String对象的不可变性
首先看一个程序 package reverse; public class Reverse { public static void main(String[] args) { String c1=n ...
- SQL点滴19—T-SQL中的透视和逆透视
原文:SQL点滴19-T-SQL中的透视和逆透视 透视 今天抽一点时间来看看透视和逆透视语句,简单的说就是行列转换.假设一个销售表中存放着产品号,产品折扣,产品价格三个列,每一种产品号可能有多种折扣, ...
- Scala中的协变,逆变,上界,下界等
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...
随机推荐
- c# var的含义与用法
VAR 是3.5新出的一个定义变量的类型其实也就是弱化类型的定义VAR可代替任何类型编译器会根据上下文来判断你到底是想用什么类型的至于什么情况下用到VAR 我想就是你无法确定自己将用的是什么类型就可以 ...
- Delphi 画箭头
procedure TForm1.Line(x, y, x2, y2: integer); begin canvas.MoveTo(x, y); canvas.LineTo(x2, y2); end; ...
- Mysql Replication 主从同步
简介: Mysql 的主从同步功能,这种解决方案是企业很常见的一种.常用于备份数据库,当客户端操作主库时,主库会产生binlog日志文件, 从库通过复制主库的binlog日志文件,然后解析成相应的 S ...
- spring 采用编程式事务
1.getCurrentSession()与openSession()的区别? * 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession() ...
- render组件
[render组件] Render继承于Component. It contians general functionality for all renderers. A renderer is wh ...
- hdu3999-The order of a Tree (二叉树的先序遍历)
http://acm.hdu.edu.cn/showproblem.php?pid=3999 The order of a Tree Time Limit: 2000/1000 MS (Java/Ot ...
- Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c
队列头文件ngx_queue.h #include <ngx_config.h> #include <ngx_core.h> #ifndef _NGX_QUEUE_H_INCL ...
- iOS导航栏自由缩放头像效果
效果图: 上代码: 先给一个self.navigationItem.titleView ,然后再放个ImangeView添加到titleView上: UIView *titleView = [[UIV ...
- .net 多线程同步的相关知识点
在多线程开发中,共享对象的同步是经常遇到的问题,以下总结了C#中线程同步的几种技术: 1,InterLocked原子操作 Decrement(ref int location);递减1 Add(ref ...
- select下拉列表
1.写 <!DOCTYPE html> <html> <head> <title></title> <script language= ...