泛型的作用和约定

提高性能

拆箱和装箱 从值类型转换为引用类型为装箱,把引用类型转换为值类型为拆箱

装箱和拆箱很容易使用,但是性能损失比较大,尤其是遍历许多项的时候。

List<T>不使用对象,在使用时定义类型

var list = new List<int>();
list.Add(44); // no boxing int item = list[0]; // mo unboxing

不妨将List<T>看做一种新的类型,不在特意的和C++的模板相比较;

泛型类型的命名约定

  1. 泛型类型的名称用T作为前缀;

  2. 泛型类型允许使用任意类替代,且只使用了一个泛型类型就可以用T作为泛型类型的名称

     public class List<T>{}
    public class LinkedList<T>{}
  3. 若泛型类型有特定需求(例如必须实现一个接口或派生自基类),或者使用了两个或多个泛型类型

    public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
    
    public delegate TOutput Converter<TInput, TOutput>(TInput from);
    
    public class SOrtedList<TKey, TValue>{}

泛型类的功能

默认值

创建泛型时,不能把null赋予泛型类型 ;在这个时候,我们就需要default,将null赋予引用类型,0赋值于值类型;

    public T GetDocument()
{
T doc = default(T);
lock(this)
{
doc = documentQueue.Dequeue();
} return doc;
}

约束

若泛型类需要调用泛型类型中的方法,就必须添加约束where

泛型支持以下几种约束类型:

约束 说明
where T: struct 对于结构约束,T必须是值类型
where T: class T必须是引用类型
where T: IFoo T必须实现接口IFoo
where T: Foo T 必须派生基类Foo
where T: new() 构造函数约束,T必须有一个默认构造函数

泛型类型也可以合并多个约束,where T: IFoo, new()约束和MyMerge<T>申明指定,T必须实现IFoo接口,且必须有一个默认构造函数,示例如下所示:

    public class MyMerge<T> where T: IFoo, new()
{
// dosomething
}

继承

泛型类型可以实现泛型接口,也可以派生自类,当然也可以派生自泛型基类;

public class Base<T>{}

public class Derived<T>: Base<T> {}    // 派生自泛型基类

当然,泛型类型派生自指定基类的类型:

public class Base<T>{}

public class Derived<T>: Base<string>{}

静态成员

泛型类的静态成员只能在类的一个实例中共享

// 定一个泛型类的静态成员
public class StaticDemo<T>
{
public static int x;
} StaticDemo<int>.x = 3; // 第一组静态字段 = 3
StaticDemo<string>.x = 4; // 第二组静态字段 = 4 Console.WriteLine(StaticDemo<int>.x); // 这里将会输出3

泛型接口

使用泛型可以定义接口,在接口定义的方法可以带泛型参数

协变

在.Net中,参数类型是协变

例如,有Shape和Circle类,Circle派生自Shape,Display方法是为了接受Shape类型的参数

public void Display(Shape object){}

现在可以传递派生自Shape基类的任意对象,例如Circle,Rectangle

Circle c = new Circle(5);
Display(c); // 这里便是协变

抗变

方法的返回类型是抗变

例如,若方法返回一个Shape,就不能把它赋予Circle,但是反过来就可以;

泛型接口的协变

若泛型类型使用out标注,泛型接口就是协变的,意味着返回类型也是T

若泛型类型使用in标注,泛型接口就是抗变的,表明传入的参数类型只能是T

C#学习笔记之泛型的更多相关文章

  1. Java泛型学习笔记 - (六)泛型的继承

    在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如: Object obj = new Integer(10); 这其实就是面向对象编程中的is ...

  2. C#学习笔记:泛型委托Action<T>和Fun<TResult>

    转自:http://www.cnblogs.com/Joetao/articles/2094271.html 本节学习了泛型委托Action<T>和Fun<TResult>两类 ...

  3. iOS学习笔记(01) - 泛型

    决定新开一坑,在不断学习的同时分享自己的学习历程给大家,既是对自己学习的记录,又希望能对大家提供些微的帮助. 这一篇文章主要来介绍泛型的意义.使用与声明方法等. 1.泛型:限制类型 1.1.泛型使用场 ...

  4. java学习笔记之泛型

    "泛型"这个术语的意思就是:"使用与许多许多的类型".泛型在编程语言中出现时,其最初的目的是希望类或方法能够具备最广泛的表达能力.如何做到这一点呢,正是通过解耦 ...

  5. Java泛型学习笔记 - (一)泛型的介绍

    一.什么是泛型:泛型的作用是用来规定一个类, 接口或方法所能接受的数据的类型. 就像在声明方法时指定参数一样, 我们在声明一个类, 接口或方法时, 也可以指定其"类型参数", 也就 ...

  6. swift学习笔记之-泛型

    //泛型(Generics) import UIKit /*泛型(Generics):泛型代码可以让你编写适用自定义需求以及任意类型的灵活可重用的函数和类型.它的可以让你避免重复的代码,用一种清晰和抽 ...

  7. 【Java学习笔记】泛型

    泛型: jdk1.5出现的安全机制 好处: 1.将运行时期的问题ClassCastException转到了编译时期. 2.避免了强制转换的麻烦. <>: 什么时候用? 当操作的引用数据类型 ...

  8. 【原】Java学习笔记027 - 泛型

    package cn.temptation.test; import java.util.ArrayList; import java.util.Iterator; public class Samp ...

  9. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

随机推荐

  1. Tomcat中相关配置详解

    tomcat的相关配置 server.xml <Server port="8005" shutdown="SHUTDOWN"> <!-- 属性 ...

  2. 线段树(lazy标记)-- 模板

    ], lazy[MAXN << ]; void PushUp(int rt) { ans[rt] = ans[rt << ] + ans[rt << | ]; } ...

  3. python开发第四篇:函数(1)

    函数 阅读目录 一 函数知识体系 二 函数基础 三 函数对象.函数嵌套.名称空间与作用域.装饰器 四 迭代器.生成器.面向过程编程 五 三元表达式.列表推导式.生成器表达式.递归.匿名函数.内置函数 ...

  4. C++-HDU3400-Line belt[三分]

    将军饮马问题的升级版 二维平面中要从A到D,给出两条线段AB,CD,分别在线段AB,CD,以及空白处的速度为P,Q,R 求最少用时 由于最优位置满足“凸性”,且两条线段可以等价,所以可以采取三分答案迭 ...

  5. 微信小程序期末复习

    过什么六一,复习不完了... 第1章作业 一.单选题(共10题,100.0分) 1以下哪个不是主流的手机操作系统? A.Android B.iOS C.Windows Phone D.Blackber ...

  6. P问题,NP问题,NPC问题学习笔记

    参考:https://www.luogu.org/blog/styx-ferryman/chu-sai-bei-kao-gan-huo-p-wen-ti-np-wen-ti-npc-wen-ti-sh ...

  7. PHP不使用第三个变量,如何实现两个变量值互换(变量值自定)

    1.使用函数: $a = 123; $b = 456; list($b,$a) =array($a,$b); 2.数学算式:$a =$a+$b-$b; $a =2; $b =1; $a =$a+$b; ...

  8. for循环与闭包

    Es5 function box(){ var arr = []; ;i<;i++){ arr[i] = (function(num){ //自我执行,并传参(将匿名函数形成一个表达式)(传递一 ...

  9. Git下载GitHub仓库里的某一个文件夹或某一个文件

    从Github上下载github上的整个项目,可以用下面指令: git clone https://github.com/XXX/xxxxx.git 其中:XXX是用户在Github上的用户名 xxx ...

  10. C编译过程

    system()调用系统命令 C语言源代码——> 预编译(1.去掉注释:2.包含文件)——> gcc -o a.o a.c 编译(编译成二进制质量)——> 链接系统库函数——> ...