(一)泛型的由来

泛型是CLR2.0新增的,泛型兼具可重用性,类型安全和效率。泛型的本质就是在程序第一次编译的为IL代码的时候,就会帮我们生成一个占位符,在git即时编译的时候,就会把占位符替换为真实的类型。

泛型的语法很简单,也没啥好说的。在我们编程中,经常碰到逻辑非常相似的模块,但是参数不一样的情况,这个时候就要考虑用到泛型。

(二)泛型的种类

1、泛型方法

2、泛型类

3、泛型接口

4、泛型委托

这里顺带提一下,泛型类和泛型接口的继承问题,大家可以自己尝试一下。

(三)泛型约束

有约束才有自由,有权利才有义务;

1、基类约束

2、接口约束

3、New()

4、引用类型约束(Class 约束)

5、值类型约束(Struct约束)

这里需要特别注明:泛型方法的返回值的问题,用default(T)

(四)协变,逆变

下面来说说,今天的重点,协变和逆变。

基本概念:out 关键字是用来协变的,in关键字是用来逆变的,协变和逆变只发生在泛型接口和泛型委托上面。

下面直接上代码,首先定义了两个类,一个是鸟类,一个是麻雀类,麻雀类继承自鸟类。

    public class Bird
{
public int Id { get; set; }
} public class Sparrow:Bird
{
public string Name { get; set; }
}

下面是简单里氏替换原则,相信大家都能理解;

             Bird bird=new Bird();
//这个不会报错,里氏替换原则
Bird sparrow=new Sparrow();
//下面这种做法会报错
//Sparrow sparrow2=new Bird();

再到下面这种情况

            List<Bird> birdList1=new List<Bird>();
//这个会报错,这个意思就是一群麻雀,等于一群鸟,在我们自己的逻辑上是没有问题的
//但是程序呢,只认父子关系,两个List之间没有父子关系。
//List<Bird> birdList2=new List<Sparrow>();
//使用下面这个方法转换一下就好了。
List<Bird> birdList2 = new List<Sparrow>().Select(d=>(Bird)d).ToList();

微软为了解决上面这种情况,在我们自己的逻辑上认为,一群麻雀肯定是一群鸟的,所以就引入了协变这个概念。协变呢,在我们平时自己编程中,确实很少用到,但是在微软的框架里面却经常看到,连最常见的IEnumerable接口是支持协变的,看定义如下:

所以刚刚那个例子可以这么写:

            IEnumerable<Bird> birds = new List<Sparrow>();
//这个协变呢,声明都是基于基类的,让我们的面向抽象的编程变得更加彻底。
//微软自己给自己打的补丁。
//其实虽然这个是协变,内部还是帮我们像上面一样,进行了类型转换,只不过这个过程是微软自己帮我们做了。
//还要特别说明一点协变,只能是返回结果。
  public interface IMyList<out T>{

    }

    public class MyList<T>:IMyList<T>{

    }

第二个是自己写的支持协变的做法。

协变的内容大概就是这么多了,下面来讲讲逆变,逆变和协变刚好相反,是声明派生类,然后用父类来赋值,这个就有点感觉像违法我们的面向对象的感觉。

上面这种就叫做逆变。逆变就是把父类反转赋值给子类。

其实.net framework里面很多关于协变,逆变的,尽管我们可能自己写代码用不到,但是我们也应该要了解和学习。

小谈C#泛型的更多相关文章

  1. DevStore开发人员服务有奖征文:小谈新浪微博开放平台

    DevStore开发人员服务有奖征文:小谈新浪微博开放平台 笔者接入新浪微博开发平台也有一段时间了,对整个平台的接入也算比較熟悉,新浪提供了统一的API接口,能够让开发人员更方便的使用API来实现自己 ...

  2. 小谈Java里的线程

    今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...

  3. 浅谈Java泛型中的extends和super关键字(转)

    通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: 向上造型一个泛型对象的引用 向下造型一个泛型对象的引用 向上造型一个泛型对象 ...

  4. 浅谈C#泛型

    一.为什么要提出泛型的概念 我们在声明对象或者方法中,对象中成员变量的定义或者函数参数都传递都要指定具体的对象类型,但是有的时候参数的类型是变化的,但是实现的功能却又差不多,这个时候我们就想,是否存在 ...

  5. 小谈Scrum敏捷开发流程

    一晃眼,有两年没有写博客了,回顾前两年,各种奔波,各种忙碌,也有不少的收获.从今天开始,我要把这些收获都分享在这里. 其实这两年,对我影响最大的是开发流程.总所周知,一个好的开发流程,对于项目的进行, ...

  6. iOS 小谈开发者中的个人、组织(公司、企业)账号

    苹果对开发者主要分为3类:个人.组织(公司.企业).教育机构.即: 1.个人(Individual) 2.组织(Organizations) 组织类又分为2个小类: (1)公司(Company) (2 ...

  7. Http与Socket小谈

    http与socket是网络编程中最为重要的概念,不管是客户端还是服务端,都是最为重要的部分,以下简述两者的关系和区别(个人见解). Http 定义 基于应用层的超文本传输协议.通常承载于TCP/IP ...

  8. 小谈 - web模仿手机打电话与正则表达式

    昨天遇到了一个很棘手的问题,就是手机端调用web端的页面,如果用编辑器插入的内容页面中有电话的的数据就要变一下格式,让手机端可以实现拨号的功能. 研究了半天就是没一点头绪,但是偶尔看到数据中每一个电话 ...

  9. 小谈React、React Native、React Web

    React有三个东西,React JS 前端Web框架,React Native 移动终端Hybrid框架,React Web是一个源码转换工具(React Native 转 Web,并之所以特别提出 ...

随机推荐

  1. redis集群运维

    Redis 的数据类型? Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zsetsorted set(有序集合) redis优势 速度快, ...

  2. python引用列表--10

    #!/usr/bin/python #coding=utf-8 #好好学习,天天向上 python=["a","b","c","d ...

  3. Codeforces Round #741 (Div. 2)

    全部题目跳转链接 A - The Miracle and the Sleeper 题意 给定\([l, r]\) 求出在这个区间内的两个数字a和b的取模的最大值 (\(a \ge b\)) 分析 上届 ...

  4. 数论同余学习笔记 Part 2

    逆元 准确地说,这里讲的是模意义下的乘法逆元. 定义:如果有同余方程 \(ax\equiv 1\pmod p\),则 \(x\) 称为 \(a\bmod p\) 的逆元,记作 \(a^{-1}\). ...

  5. AT2650 [ARC077C] guruguru

    可以发现,如果我们枚举每个理想亮度 \(X\) 然后再求在这个理想亮度情况下的答案是非常难维护的. 不妨反过来,考虑每个位置 \(i, i + 1\) 之间对每个理想亮度 \(X\) 减少次数的贡献. ...

  6. FileInputStream 类与 FileReader 类的区别

    FileInputStream 类与 FileReader 类的区别: 两个类的构造函数的形式和参数都是相同的,参数为 File 对象或者表示路径的 String ,它们到底有何区别呢? FileIn ...

  7. Arch Linux遇到的坑(下)

    明天就要开学,终于赶忙又熟悉了新环境的用法,现在已经基本满足了日常需求,再记录一些坑-. 电脑没有声音 因为上次离奇的自己好了,我就没有再管了,但是后来使用chrome的时候还是没有声音,我就用了图形 ...

  8. 问题描述:Navicat连不上MySQL数据库

    发现Navicat连不上MySQL后我首先觉得是MySQL的服务没有打开, 然后再cmd里面 启动MySQL服务 输入: net start mysql 发现没有此服务,然我网上找了一下 先初始化My ...

  9. 公式编辑器CVE-2018-0798样本分析

      当前样本是一个RTF文档,内嵌一个公式编辑器对象,该对象利用Office编辑器漏洞CVE-2018-0798执行shellcode,对EQNEDT32.exe进行代码注入,执行恶意代码.   使用 ...

  10. Large Sacle Distributed Deep Networks

    本文是谷歌发表在NeurIPS 2012上的一篇论文,主要讨论了在几万个CPU节点上训练大规模深度网络的问题,并提出了一个名为DistBelief的软件框架.在该框架下实现了两种大规模分布式训练算法: ...