using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MyGeneric.CC
{
/// <summary>
/// 逆变(contravariant)与协变(covariant):只能用在接口和委托上面
/// out “协变”->”和谐的变”->”很自然的变化”->string->object :协变。 负责修饰返回值
/// in “逆变”->”逆常的变”->”不正常的变化”->object->string 逆变。 负责修饰参数
/// </summary>
public class CCTest
{
public static void Show()
{
Child child = new Child();
Parent parent = new Parent();
Parent parent77 = new Child();
Parent parent88 = (Parent)child;
{
List<Parent> parentList = new List<Parent>();
//List<Parent> parentList3 = new List<Child>();//需要转换才行 List<Parent> parentList1 = new List<Child>().Select(c => (Parent)c).ToList();//需要自己转换 IEnumerable<Parent> parentList2 = new List<Child>();//协变 只能是返回值,返回的Child必然是Parent的 Action<Child> act = new Action<Child>(c => { });//按说都是child才行 Action<Child> act1 = new Action<Parent>(c => { });//l使用act1的时候,参数只能是Child,必然满足lambda表达式对parent的类型要求 act(child);
act1(child);
}
{
//增强了接口、委托的适用范围,同时保证了类型安全
IMyList<Child, Parent> list1 = new MyList<Child, Parent>();
{
list1.Show(child);
Parent parent1 = list1.Get();
Parent parent2 = list1.Do(child);
}
IMyList<Child, Parent> list2 = new MyList<Child, Child>();
{
list2.Show(child);
Parent parent1 = list2.Get();
Parent parent2 = list2.Do(child);
}
IMyList<Child, Parent> list4 = new MyList<Parent, Parent>();
{
list4.Show(child);
Parent parent1 = list4.Get();
Parent parent2 = list4.Do(child);
}
IMyList<Child, Parent> list3 = new MyList<Parent, Child>();
{
list3.Show(child);
Parent parent1 = list3.Get();
Parent parent2 = list3.Do(child);
}
}
} }
public class Parent
{
} public class Child : Parent
{
} public interface IMyList<in inT, out outT>
{
void Show(inT t);
outT Get();
outT Do(inT t); ////out 只能是返回值 in只能是参数
//void Show1(outT t);
//inT Get1(); } public class MyList<T1, T2> : IMyList<T1, T2>
{ public void Show(T1 t)
{
Console.WriteLine(t.GetType().Name);
} public T2 Get()
{
Console.WriteLine(typeof(T2).Name);
return default(T2);
} public T2 Do(T1 t)
{
Console.WriteLine(t.GetType().Name);
Console.WriteLine(typeof(T2).Name);
return default(T2);
}
}
}

逆变(contravariant)与协变(covariant):只能用在接口和委托上面的更多相关文章

  1. 协变(covariant)和逆变(contravariant)

    我们知道子类转换到父类,在C#中是能够隐式转换的.这种子类到父类的转换就是协变. 而另外一种类似于父类转向子类的变换,可以简单的理解为“逆变”. 上面对逆变的简单理解有些牵强,因为协变和逆变只能针对接 ...

  2. 不变(Invariant), 协变(Covarinat), 逆变(Contravariant) : 一个程序猿进化的故事

    阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类 ...

  3. C#4.0新特性(3):变性 Variance(逆变与协变)

    一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值):逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确. 通常,协 ...

  4. Java逆变(Covariant)和协变(Contravariant)

    1. 定义 逆变和协变描述的经过类型变换后的类型之间的关系.假如A和B表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么 如果A ≤B,f(A) ≤f(B),那么f是协变 如果A ≤B,f(B ...

  5. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

  6. Scala中的协变,逆变,上界,下界等

    Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...

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

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

  8. Scala 基础(十六):泛型、类型约束-上界(Upper Bounds)/下界(lower bounds)、视图界定(View bounds)、上下文界定(Context bounds)、协变、逆变和不变

    1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 Li ...

  9. C#4.0泛型的协变,逆变深入剖析

    C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...

随机推荐

  1. win10连接宽带,拨号提示错误720:不能建立到远程计算机的连接,解决方法

    使用账号密码登录时,一直报720错误.解决方法是卸载以下IP驱动.卸载之后重新连接就正常了.亲测有效

  2. Mysql ssl 连接

    在Azure创建了一个Mysql5.7服务,因为默认使用ssl连接,需要下载Azure的证书,并使用openssl生成客户端的证书.具体流程参考官方文档 大致步骤: 下载根证书, 安装openssl, ...

  3. day03 文件操作

    目录 1.文件操作实例 2.文件常用操作 3.with模块操作文件 常用实例,把文件里面的内容读出来做成字典的形式在做成字列表展示. 1.精简版. lst = []f = open("fil ...

  4. *&p理解

    要明白这个需明白两个基础: 运算符*优先级高于&, 两个运算符都是从右向左结合运算 所以,*&a 的意思就是先运算 *,得到 指针,再通过 &,获取指针的引用 如果不理解,继续 ...

  5. update_engine-DownloadAction(二)

    在update_engine-DownloadAction(一)中对DownloadAction介绍到了DeltaPerformer的Write方法.下面开始介绍Write方法. src/system ...

  6. vue-cli环境配置

    1.安装npm 从node.js官网下载并安装node node -v 命令,查看node的版本,若出现相应的版本号,则说明你安装成功了. npm包管理器,是集成在node中的,所以安装了node也就 ...

  7. [蓝桥杯]PREV-21.历届试题_回文数字

    问题描述 观察数字:, 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的.这样的数字叫做:回文数字. 本题要求你找到一些5位或6位的十进制数字.满足如下要求: 该数字的各个数位之和等于输入 ...

  8. 使用docker加载已有镜像安装Hyperledger Fabric v1.1.0

    背景 每次在新的服务器上安装Hyperledger Fabric网络时,通过fabric官方提供的脚本安装时,需要从网络上down下近10G的fabric相关镜像,这个过程是漫长及痛苦的,有时因网络问 ...

  9. 廖雪峰Java8JUnit单元测试-2使用JUnit-3参数化测试

    参数化测试: 可以把测试数据组织起来 用不同的测试数据调用相同的测试方法

  10. qnx gpio

    in order to set gpio in qnx, you can use msmgpiotool # msmgpiotool gpiotool usage: gpiotool <comm ...