逆变(contravariant)与协变(covariant):只能用在接口和委托上面
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):只能用在接口和委托上面的更多相关文章
- 协变(covariant)和逆变(contravariant)
我们知道子类转换到父类,在C#中是能够隐式转换的.这种子类到父类的转换就是协变. 而另外一种类似于父类转向子类的变换,可以简单的理解为“逆变”. 上面对逆变的简单理解有些牵强,因为协变和逆变只能针对接 ...
- 不变(Invariant), 协变(Covarinat), 逆变(Contravariant) : 一个程序猿进化的故事
阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类 ...
- C#4.0新特性(3):变性 Variance(逆变与协变)
一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值):逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确. 通常,协 ...
- Java逆变(Covariant)和协变(Contravariant)
1. 定义 逆变和协变描述的经过类型变换后的类型之间的关系.假如A和B表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么 如果A ≤B,f(A) ≤f(B),那么f是协变 如果A ≤B,f(B ...
- 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程
额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...
- Scala中的协变,逆变,上界,下界等
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...
- 协变(covariance),逆变(contravariance)与不变(invariance)
协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...
- Scala 基础(十六):泛型、类型约束-上界(Upper Bounds)/下界(lower bounds)、视图界定(View bounds)、上下文界定(Context bounds)、协变、逆变和不变
1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 Li ...
- C#4.0泛型的协变,逆变深入剖析
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...
随机推荐
- w3c
normative adj. 规范的,标准的errata n. 勘误表:正误表(erratum的复数)Substantive adj. 有实质的:大量的:真实的:独立存在的i ...
- C++vector针对排序操作练习
目的: 定义5个学生,包含名字和分数,对成员进行从大到小排序,并输出 #include <iostream> #include <cstring> #include <v ...
- 关于mysql自增主键
对于mysql表(其他数据库没测试过) 如果定义了自增主键,并且手动设置了主键的值,那么当再次自增创建数据的时候,回在设置的主键值的基础上进行自增. 如(id是主键): 起始插入(3,1),而后手动插 ...
- 使用 random() 生成礼包码
需求:生成100个游戏礼包码 具体如下 # 1.构造100个5位随机数 listNumA = [] for n in range(100): listNumA.append(random.randin ...
- python基础知识2---核心风格
阅读目录 一.语句和语法 二.变量定义与赋值 三.内存管理 内存管理: 引用计数: 简单例子 四.python对象 五.标识符 六.专用下划线标识符 七.编写模块基本风格 八.示范 一.语句和语法 # ...
- ORACLE 数据库使用正则表达式重新计算指定位置的数字为新的数字
昨天工作中遇到这个问题: 有一个这样的字符串expression变量,里面可能存储的值类似于以下[Index_CivilWork,0]*(1+[Y10814,1])/[Y10674,1] [300,1 ...
- 清空Sql server日志
日志文件时间长了很大很讨厌,这样清空 1.分离数据库 2.将原数据库的log文件改名 3.附加数据库,在log文件中会显示没有发现,点击删除按钮 4.确定即可
- centos7卸载旧jdk安装新jdk1.8
卸载旧JDK版本 需卸载centos7自带的JDK1.7 rpm -qa|grep jdk 列出已安装jdk版本 rpm -e --nodeps java-1.7.0-openjdk-1.7. ...
- Java邮件发送
Java中发送邮件的方法之一,需要用到spring框架集成的JavaMailSenderImpl.SimpleMailMessage两个实现类. 一,创建一个service,代码如下: public ...
- Go 1.11 Module 介绍
title: "Go 1.11 Module" date: 2018-10-26T23:50:56+08:00 draft: false --- Go 1.11 Module 介绍 ...