C# 泛型的协变
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Person chinese2 = new Chinese();//chinese继承自person,所以允许转换 List<Person> people = new List<Person>();
//以下代码不允许。
//一群中国人难道不是一群人??
//1、list<people>与list<chinese>没有继承关系。
//2、若成立,就可以向这个列表中写入people类型数据,也可以写入chinese类型数据,这是类型不安全的
List<Person> chineses = new List<Chinese>(); //另外一个更容易理解的例子
//所有类都是Object的子类,若这个转换成立,那么list里可以有各种各样的数据。
List<object> list = (List<object>)people; //协变
IMyList<Person> myPeople = new MyList<Chinese>();
myPeople.Item = new Person();//协变的属性是只读的,所以报错 //协变的前提:
//1、只有泛型接口和泛型委托才可以协变,详见MyList2类
//2、协变的类型实参只能是引用类型,不能是值类型
IMyList<object> myList1 = new MyList<int>(); }
} class Person
{
public int ID { get; set; }
public string Name { get; set; }
} class Chinese: Person
{
public string Gender { get; set; }
}
/// <summary>
/// c#4.0起,使用out 类型参数修饰符允许协变。
/// 协变类型参数只能是只读;
/// out修饰符会让编译器验证T是否真的只用作“输出”,且永远不用于形参或属性的赋值方法
/// </summary>
/// <typeparam name="T"></typeparam>
interface IMyList< out T>
{ public T Item { get;}
/// <summary>
/// out 修饰的类型参数必须是只读,所以代码报错
/// </summary>
public T Item2 { get; set; }
/// <summary>
/// out 修饰的类型参数不能做为形参,所以代码报错
/// </summary>
/// <param name="t"></param>
public void SetValue(T t); }
/// <summary>
/// 实现接口类
/// </summary>
/// <typeparam name="T"></typeparam>
class MyList<T> : IMyList<T>
{
public T Item => default(T); public T Item2 { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void SetValue(T t)
{ }
}
/// <summary>
/// 只有泛型接口和泛型委托才可以协变。泛型类型与结构永远不可协变
/// </summary>
/// <typeparam name="T"></typeparam>
class MyList2<out T>
{ }
C# 泛型的协变的更多相关文章
- .NET 4.0中的泛型的协变和逆变
转自:http://www.cnblogs.com/jingzhongliumei/archive/2012/07/02/2573149.html 先做点准备工作,定义两个类:Animal类和其子类D ...
- Java用通配符 获得泛型的协变和逆变
Java对应泛型的协变和逆变
- 转载.NET 4.0中的泛型的协变和逆变
先做点准备工作,定义两个类:Animal类和其子类Dog类,一个泛型接口IMyInterface<T>, 他们的定义如下: public class Animal { } public ...
- java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去
class Fruit{} class Apple extends Fruit{} class SubApple extends Apple{} class Orange extends Fruit{ ...
- Java泛型的协变
在上篇<Java泛型的基本使用>这篇文章中遗留以下问题,即将子类型也能添加到父类型的泛型中,要实现这种功能必须借助于协变. 实验准备 现在在上篇文章展示的Decorator类型的基础上,增 ...
- Kotlin泛型与协变及逆变原理剖析
在上一次https://www.cnblogs.com/webor2006/p/11234941.html中学习了数据类[data class]相关的知识,这次会学习关于泛型相关的东东,其中有关于泛型 ...
- Java泛型的协变与逆变
泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods have same erasure ...
- C#4.0泛型的协变,逆变深入剖析
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...
- C# 泛型的协变和逆变
1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量.协变和逆变是两个相互对立的概念: 如 ...
- C# 泛型的协变和逆变 (转载)
1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量. 协变和逆变是两个相互对立的概念: ...
随机推荐
- Centos-转换或复制文件-dd
dd 转换或复制文件,同时可以对设备进行备份 相关选项 if 输入文件,可以是设备 of 输出文件,可以是输出设备 bs 指定一个block大小,默认为 512字节 count 指定bs数量
- windows 漏洞列表
漏洞列表 #Security Bulletin #KB #Description #Operating System CVE-2017-0213 [Windows COM Eleva ...
- C语言中最常用的标准库函数
标准头文件包括: <asset.h> <ctype.h> <errno.h> <float.h> <limits ...
- Linux 下 svn 场景实例及常用命令详解
一.SVN使用场景实例 问题: 在使用svn做为版本控制系统的软件开发中,经常会有这样的需求:在工作复本目录树的不同目录中增加了很多文件,但未纳入版本控制系统,这时如果使用svn add命令一个一个的 ...
- MySQL数据库的完全备份与恢复
前言 在生产环境中,数据的安全性是至关重要的,任何数据的丢失都可能产生严重的后果,正确的数据库操作是实际环境下不可缺少的. 一.数据库备份的分类 1.1 从物理与逻辑的角度,备份的分类 物理备份:对数 ...
- css做模糊处理
-webkit-filter: blur(9px); filter: blur(9px);
- Signature Scanning(中文暂时译为"特征码扫描")是在C++(起码我是用C++^^)开发中很好的一种方式
1.介绍 本文主要简单介绍在没有代码的情况下,如何从一个动态链接库中获取某个函数的址.主要实现方式为Signature Scanning(特征码扫描) 2.什么是Signature Scanning( ...
- GML与KML的区别
1.GML是基于XML的地理信息的传输.存储编码,它包括空间的和非空间的地理特征和地理范畴.GML是空 间数据编码.传输.存储.发布的国际标准KML是一个OGC标准 2.GML专注于地理信息的结构与内 ...
- Android开发签名证书的生成
现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套[Android进阶学习视频].[全套Android面试秘籍].[Android知识点PDF] ...
- 推荐算法之: DeepFM及使用DeepCTR测试
算法介绍 左边deep network,右边FM,所以叫deepFM 包含两个部分: Part1: FM(Factorization machines),因子分解机部分 在传统的一阶线性回归之上,加了 ...