[C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型
引言:
前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解,那就让我们一起进入本专题的学习的。
一、泛型的是什么
泛型的英文解释为generic,当然我们查询这个单词时,更多的解释是通用的意思,然而有些人会认为明明是通用类型,怎么成泛型了的,其实这 两者并不冲突的,泛型本来代表的就是通用类型,只是微软可能有一个比较官方的此来形容自己引入的特性而已,既然泛型是通用的, 那么泛型类型就是通用类型的,即泛型就是一中模子。 在生活中,我们经常会看到模子,像我们平常生活中用的桶子就是一个模子,我们可以用桶子装水,也可以用来装油,牛奶等等,然而把这些都装进桶子里面之后,它们都会具有桶的形状(水,牛奶和油本来是没有形的),即具有模子的特征。同样,泛型也是像桶子一样的模子,我们可以用int类型,string类型,类去实例化泛型,实例化之后int,string类型都会具有泛型类型的特征(就 是说可以使用泛型类型中定义的方法,如List<T>泛型,如果用int去初始化它后,List<int>的实例就可以用 List<T>泛型中定义的所有方法,用string去初始化它也一样,和我们生活中的用桶装水,牛奶,油等非常类似)
二、C# 2.0为什么要引入泛型
大家通过第一部分知道了什么是泛型,然而C#2.0中为什么要引入泛型的?这答案当然是泛型有很多好处的。下面通过一个例子来说明C# 2.0中为什么要引入泛型,然后再介绍下泛型所带来的好处有哪些。
当我们要写一个比较两个整数大小的方法时,我们可能很快会写出下面的代码:
public class Compare
{
// 返回两个整数中大的那一项
public static int Compareint(int int1, int int2)
{
if (int1.CompareTo(int2) > 0)
{
return int1;
} return int2;
}
}
然而需求改变为又要实现比较两个字符串的大小的方法时,我们又不得不在类中实现一个比较字符串的方法:
// 返回两个字符串中大的一项
public static string Comparestring(string str1, string str2)
{
if (str1.CompareTo(str2) > 0)
{
return str1;
} return str2;
}
如果需求又改为要实现比较两个对象之间的大小时,这时候我们又得实现比较两个对象大小的方法,然而我们中需求中可以看出,需求中只是比较的类型不一样的,其实现方式是完全一样的,这时候我们就想有没有一种类型是通用的, 我们可以把任何类型当做参数传入到这个类型中去实例化为具体类型的比较,正是有了这个想法,同时微软在C#2.0中也想到了这个问题,所以就导致了 C#2.0中添加了泛型这个新的特性,泛型就是——通用类型,有了泛型之后就可以很好的帮助我们刚才遇到的问题的,这样就解决了我们的第一个疑问——为什 么要引入泛型。下面是泛型的实现方法:
public class Compare<T> where T : IComparable
{
public static T CompareGeneric(T t1, T t2)
{
if (t1.CompareTo(t2) > 0)
{
return t1;
}
else
{
return t2;
}
}
}
这样我们就不需要针对每个类型实现一个比较方法,我们可以通过下面的方式在主函数中进行调用的:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(Compare<int>.CompareGeneric(3, 4));
Console.WriteLine(Compare<string>.CompareGeneric("abc", "a"));
Console.Read();
}
}
通过上面的代码大家肯定可以理解C# 2.0中为什么要引入泛型的,然而泛型可以给我们带什么好处的呢?从上面的例子可以看出,泛型可以帮助我们实现代码的重用,大家很清楚——面向对象中的继承也可以实现代码的重用,然而泛型提供的代码的重用,确切的说应该是 “算法的重用”(我理解的算法的重用是我们在实现一个方法中,我们只要去考虑如何去实现算法,而不需要考虑算法操作的数据类型的不同,这样的算法实现更好的重用,泛型就是提供这样的一个机制)。
然而泛型除了实现代码的重用的好处外,还有可以提供更好的性能和类型安全,下面通过下面一段代码来解释下为什么有这两个好处的。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics; namespace GeneralDemo
{
public class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch(); // 非泛型数组
ArrayList arraylist = new ArrayList(); // 泛型数组
List<int> genericlist= new List<int>();
// 开始计时
stopwatch.Start();
for (int i = 1; i < 10000000; i++)
{
genericlist.Add(i);
////arraylist.Add(i);
} // 结束计时
stopwatch.Stop(); // 输出所用的时间
TimeSpan ts = stopwatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds/10);
Console.WriteLine("运行的时间: " + elapsedTime);
Console.Read();
}
}
}
当我们把 arraylist.Add(i);这行代码注释掉来测试向泛型数组中加入数据的运行时间,下面是我机器的上运行的一个截图:

当我们把 genericlist.Add(i);这行代码注释掉来测试向一个非泛型数组中加入数据的运行时间,下面附上我机器上的运行的时间截图:

从两个结果中就可以明显看出 向泛型数组中的加入数据的效率远高于非泛型数组。有图有真相,这样就充分说明泛型的另一个好处——高性能,然而泛型类型也保证了类型安全(大家都知道,C#是一个强类型的语言的,强类型指的是在每定义一个变量都需要指定变量的类型),当我们向这个泛型genericlist数组中添加string类型的值时,此时就会造成编译器报错 “无法从“string”转换为’int‘ ”
三、小结
本专题主要和大家分享了C# 2.0中为什么会引入委托,以及委托的好处,相信通过上面的介绍大家可以对委托有一个简单的认识以及对于泛型所带来的好处也有一个全面的认识,对于泛型的高性能本专题并没有给出原因,这个内容将会在下面一个专题向大家介绍。
相关资料:
- asp.net|Linq实践系列(1):一句代码实现DataTable全文搜索(Full Text Search)
- asp.net|Silverlight Socket 使用代理连接服务器
- asp.net|使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)
- asp.net|[C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型
- asp.net|让开发变得更快速、更简单——类型化DataSet的使用
- asp.net|.NET自定义事件小结
- asp.net|服务器端控件TextBox 设为只读属性后无法获取javascript给其赋的值
[C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型来源网络,如有侵权请告知,即处理!
[C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型的更多相关文章
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- C#基础知识梳理系列
1. 这个系列深入的从IL层面谈了C#各种基本知识的本质,十分值得学习: http://www.cnblogs.com/solan/category/398748.html
- [转载收藏]C#基础知识梳理系列十一:垃圾回收机制
摘 要 基于.NET平台的开发语言中,最让开发人员爽的一点就是垃圾回收处理机制,在编码过程中,终于可以解放你的双手来关注更重要的事情.很多的资料中在讲到.NET中的垃圾回收机制时都说"CLR ...
- MySQL 基础知识梳理学习(六)----锁
1.什么是锁: 对共享资源进行并发访问控制,提供数据的完整性和一致性. 2.锁的区别: 类型 lock latch 对象 事务 线程 保护 数据库内容 内存数据结构 持续时间 整个事务过程 临界资源 ...
- [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式
SQL 基础知识梳理(六)- 函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(七)- 集合运算
SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
随机推荐
- 预编译 .pch文件
如果工程导入了其他编程语言文件混编的时候 .pch文件会在程序开始的时候导入所有头文件,需要 '预编写命令' 区分编程语言的头文件. 下面报错就是因为工程导入了.c 文件 .pch全局导入了O ...
- hdu 2037
PS: - -原本想的是排序开始时间和消耗时间..后来想到可以排序结束时间..后来还wa了一次,因为排序的时候溢出了 思路: 1 3 //13 4 //20 7 3 8 2 9 5 10 //36 ...
- PHP面向对象的程序设计一些简单的概念
一.面向对象的概述 数组和对象,都属于PHP中的复合类型(一个变量可以存储多个单元) 对象比数组更强大,不仅可以存储多个数据,还可以将函数存在对象中 对象的三大特性:封装,继承,多态 面向对象编 ...
- 【Tsinghua OJ】循环移位(Cycle)
Description Cycle shifting refers to following operation on the sting. Moving first letter to the en ...
- JQuery源码分析(三)
jQuery中ready与load事件 jQuery有3种针对文档加载的方法 $(document).ready(function() { // ...代码... }) //document read ...
- AmazeUI布局
AmazeUI使用了12列的响应式网络系统.使用时需在外围容器上添加.am-g class,在列上添加.am-u-[sm|md|lg]-[1-12] class,然后根据不同的屏幕需求设置不同的宽度. ...
- java作业3
Java字段初始化的规律: 静态初始化生成实例之后(就是new之后)变成你赋给它的值 ,先执行静态初始化,如果没有实例化,按照初始化块和构造方法在程序中出现的顺序执行. 当多个类之间有继承关系时,创建 ...
- 中文圣经 for Android
中文圣经(For Android) 目前,中文圣经App包含了如下圣经版本: 和合本 现代中文译本 吕振中译本 中文新译本 英文标准本(ESV) King James Version(KJV) New ...
- 使用SSMS 2014将本地数据库迁移到Azure SQL Database
使用SQL Server Management Studio 2014将本地数据库迁移到Azure SQL Database的过程比较简单,在SSMS2014中,有一个任务选项为“将数据库部署到Win ...
- 怎么在手机浏览器上访问电脑本地的文件,局域网内,自建WiFi也可以
首先,电脑要有Mysql+Apache+PHP环境,我直接用Wampsever,开启环境后手机和电脑要再同一个局域网内,然后电脑上打开win+R,输入cmd,再输入ipconfig,就可以看着这台的电 ...