泛型(Generics)
Framework类库中的泛型
泛型可以使代码重用,提高开发效率
CLR允许在引用类型、值类型或接口中定义泛型方法;
CLR允许创建泛型引用类型、泛型值类型(枚举不允许创建)、泛型委托类型和泛型接口类型;
System.Collections.Generics中定义了List<T>,<T>表示它操作的是一个未指定数据类型;定义泛型类型或方法时,T是一个变量名,在源代码中能够使用一个数据类型的任何位置都能用T,例如方法参数、返回值等等。
泛型参数变量要么称为T,要么以T开头(如Tkey,TEvent...)
定义好泛型类型后,使用泛型类型或方法时,制定具体的类型实参
var validationResult = new List<ValidationResult>();
泛型的优势
- 源代码保护
使用泛型算法时候,不需要了解算法内部的具体实现 - 类型安全
将泛型算法运用于一个具体的类型,只有与数据类型兼容算法的对象才能使用算法,若不兼容,便会编译错误或运行异常 - 更加清晰的代码
由于编译器强制类型安全,减少了代码中的转型次数 - 更佳的性能
由于装箱会造成性能的浪费,通过泛型避免了装箱
下面是一段泛型与非泛型的算法性能测试对比
class Program
{
static void Main(string[] args)
{
ValueTypePreTest();
ReferenceTypePreTest();
Console.ReadKey();
}
private static void ValueTypePreTest()
{
const int count = 10000000;
using (new OperationTimer("List<Int32>"))
{
List<int> l = new List<int>();
for (int i = 0; i < count; i++)
{
l.Add(i);
int x = l[i];
}
l = null;//确保进行垃圾回收
}
using (new OperationTimer("ArraryList of Int32"))
{
ArrayList arr = new ArrayList();
for (int i = 0; i < count; i++)
{
arr.Add(i);
int x = (int)arr[i];
}
arr = null;
}
}
private static void ReferenceTypePreTest()
{
const int count = 10000000;
using (new OperationTimer("List<String>"))
{
List<string> l = new List<string>();
for (int i = 0; i < count; i++)
{
l.Add("X");
string x = l[i];
}
l = null;//确保进行垃圾回收
}
using (new OperationTimer("ArraryList of String"))
{
ArrayList arr = new ArrayList();
for (int i = 0; i < count; i++)
{
arr.Add("X");
string x = (string)arr[i];
}
arr = null;
}
}
}
class OperationTimer : IDisposable
{
private long _start;
private string _text;
private int _collectionCount;
public OperationTimer(string text)
{
_text = text;
_collectionCount = GC.CollectionCount(0);
_start = Stopwatch.GetTimestamp();
}
public static void PreparForPeration()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
public void Dispose()
{
Console.WriteLine("{0,6:###.00} seconds(GCs={1,3}) {2}",
(Stopwatch.GetTimestamp() - _start) / (double)Stopwatch.Frequency,
GC.CollectionCount(0) - _collectionCount,
_text
);
}
}

Wintellect的Power Collections库
Wintellect公司开发的一些C++集合类库
泛型基础结构
开放类型和封闭类型
具有泛型类型参数的类型称为开放类型(例如:Directory<,>),CLR禁止构造开放类型的任何实例
代码引用一个泛型类型时,可指定一组泛型类型实参,假如为所有类型实参传递都是实际数据类型,称为封闭类型(例如:List<string>)
开放类型和封闭类型
具有泛型类型参数的类型称为开放类型(例如:Directory<,>),CLR禁止构造开放类型的任何实例
代码引用一个泛型类型时,可指定一组泛型类型实参,假如为所有类型实参传递都是实际数据类型,称为封闭类型(例如:List<string>)
泛型类型和继承
泛型类型任然是一种类型,它可以从其他类型派生。
泛型类型的同一性
不要为了简化代码而定义一个新的类型继承泛型,这样会散失同一性和相等性,可以通过下面的方式简化代码输入
using DateTimeList=System.Collections.Generic.List<DateTime>;
代码爆炸
CLR 优化了泛型类型的编译代码,避免了每次都要为不同的泛型类型生成对应的代码
泛型接口
通过泛型接口避免值类型发生装箱
public interface IEnumerator<T>:IDisposable,IEnumerator
{
T Current{get;}
}
泛型委托
保证任何类型的对象都能以一种类型安全的方式传给回调方法;而且泛型委托也是为了避免一个值类型实例在传递给回调方法时不再发生装箱
委托和接口的协变和逆变泛型类型实参
泛型方法
泛型除了可以定义类型的参数,还可以为方法定义一个只作用域于方法的类型参数
泛型的类型推断
public static void Display<T>(T input){
System.Console.WriteLine(input);
}
Display(123);
Display("aaa")
泛型和其他成员
在C#中,属性、事件、索引器、构造函数等成员是不能有类型参数的,但是在泛型类型中,这些成员的代码是可以使用类型参数的;
C#不允许他们指定自己的泛型类型参数,C#团队认为开发人员很少需要将这些成员作为泛型使用,当然为这些成员添加泛型代价也很高
可验证性和约束
泛型(Generics)的更多相关文章
- [19/03/23-星期六] 容器_ 泛型Generics
一.概念 生活中的容器不难理解,是用来容纳物体的,程序中的“容器”也有类似的功能,就是用来容纳和管理数据. 数组就是一种容器,可以在其中放置对象或基本类型数据. ---优势:是一种简单的线性序列,可以 ...
- Java 泛型(Generics)
Generics, 类似C++中的模版. 允许在定义类和接口的时候使用类型参数(type parameters), 声明的类型参数在使用的时候用具体的类型来替换. 如 ArrayList<Str ...
- Java 泛型(Generics) 综述
一. 引子 一般的类和方法.仅仅能使用详细类型:要么是基本类型.要么是自己定义类型.假设要编写能够应用于多种类型的代码,这样的刻板的限制对代码的束缚就会非常大. 多态算是一种泛化机制,但对代码的约束还 ...
- Welcome-to-Swift-22泛型(Generics)
泛型代码可以确保你写出灵活的,可重用的函数和定义出任何你所确定好的需求的类型.你可以写出避免重复的代码,并且用一种清晰的,抽象的方式表达出来. 泛型是Swift许多强大特征中的其中一个,许多Swift ...
- [JavaCore]JAVA中的泛型
JAVA中的泛型 [更新总结] 泛型就是定义在类里面的一个类型,这个类型在编写类的时候是不确定的,而在初始化对象时,必须确定该类型:这个类型可以在一个在里定义多个:在一旦使用某种类型,在类方法中,那么 ...
- Java1.5泛型指南中文版(Java1.5 Generic Tutorial)
Java1.5泛型指南中文版(Java1.5 Generic Tutorial) 英文版pdf下载链接:http://java.sun.com/j2se/1.5/pdf/generics-tutori ...
- java泛型小问题
几年前当Java5还未正式发布的时候,看到过一些人写的介绍Tiger中的新特性,当时对我第一感觉冲击最大的就是泛型(generics)和注释(annotation),因为它们直接影响了我们编码的语法习 ...
- 泛型-----键值对----映射 hashmap--entry中key value 链表
connection map 集合框架 * java.util.Collection *集合与数组相似,也是可以保存一组元素,并且提供了操作元素的相关方法. *collection是所有集合的顶级接口 ...
- Java下的框架编程(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)
Java 虽然没有动态语言般暴起,但仍然天连天,水接水的生出好多框架技术---反射(reflection),泛型(generics),元数据(annotation),proxies(proxy/cgl ...
随机推荐
- Spring:源码解读Spring IOC原理
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- 在.NET中使用管道将输出流转换为输入流
最近在写一段代码,将本地文件压缩加密后发送到服务器,发送到服务器的类用一个输入流作为参数获取要上传的数据,而压缩类和加密类都是输出流. 如何将输出流转换为输入流,最直观的方法是缓存输出流的全部内容到内 ...
- 图解C#的值类型,引用类型,栈,堆,ref,out
C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...
- Xcode升级 Alcatraz 无法使用
Alcatraz 主要是可以管理xcode 插件 随着 Xcode 的更新 Alcatraz 有可能无法使用 以下是解决办法: 1,关闭Xcode 2,如果已经安装过 Alcatraz,先卸载掉,然后 ...
- LInux MySQL 数据库 的一些操作
数据库安装: ………… 创建数据库连接新用户: 1.登录mysql #mysql -u root -p 2.新增用户 insert into mysql.user(Host,User,Password ...
- 利用扩展事件进行调优和Troubleshooting PPT分享
本篇主题是我在2015年中国数据库大会(DTCC)上的分享,扩展事件从2008版本出来到现在已经有6-7年,国内却很少有相关资料和使用,现在分享一下PPT,希望对大家有所帮助. 可 ...
- 深入理解DOM节点类型第三篇——注释节点和文档类型节点
× 目录 [1]注释节点 [2]文档类型 前面的话 把注释节点和文档类型节点放在一起是因为IE8-浏览器的一个bug.IE8-浏览器将标签名为"!"的元素视作注释节点,所以文档声明 ...
- .Net 转战 Android 4.4 日常笔记目录
.Net 转战 Android 4.4 日常笔记(1)--工具及环境搭建 .Net 转战 Android 4.4 日常笔记(2)--HelloWorld入门程序 .Net 转战 Android 4.4 ...
- Power BI官方视频(1) Power BI Desktop 7月份更新功能概述
2016年7月,Power BI Desktop进行了一些功能更新,提高整体的用户体验.同时也有一些新的和令人兴奋的功能.看看大概介绍,更新功能要点: 本文原文地址:Power BI官方视频(1) P ...
- Android获取可存储文件所有路径
引言:大家在做app开发的时候,基本都会保存文件到手机,android存储文件的地方有很多,不像ios一样,只能把文件存储到当前app目录下,并且android手机由于厂家定制了rom,sdcard的 ...