[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中为什么会引入委托,以及委托的好处,相信通过上面的介绍大家可以对委托有一个简单的认识以及对于泛型所带来的好处也有一个全面的认识,对于泛型的高性能本专题并没有给出原因,这个内容将会在下面一个专题向大家介绍。
[C# 基础知识系列]专题六:泛型基础篇——为什么引入泛型的更多相关文章
- [C# 基础知识系列]专题九: 深入理解泛型可变性
引言: 在C# 2.0中泛型并不支持可变性的(可变性指的就是协变性和逆变性),我们知道在面向对象的继承中就具有可变性,当方法声明返回类型为Stream,我们可以在实现中返回一个FileStream的类 ...
- [C# 基础知识系列]专题七: 泛型深入理解(一) (转载)
引言: 在上一个专题中介绍了C#2.0 中引入泛型的原因以及有了泛型后所带来的好处,然而上一专题相当于是介绍了泛型的一些基本知识的,对于泛型的性能为什么会比非泛型的性能高却没有给出理由,所以在这个专题 ...
- [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托
转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...
- [C# 基础知识系列]专题八: 深入理解泛型(二)
引言: 本专题主要是承接上一个专题要继续介绍泛型的其他内容,这里就不多说了,就直接进入本专题的内容的. 一.类型推断 在我们写泛型代码的时候经常有大量的"<"和"& ...
- [C# 基础知识系列]专题十六:Linq介绍
转自http://www.cnblogs.com/zhili/archive/2012/12/24/Linq.html 本专题概要: Linq是什么 使用Linq的好处在哪里 Linq的实际操作例子— ...
- [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)
当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...
- [C# 基础知识系列]专题三:如何用委托包装多个方法——委托链 (转载)
引言: 上一专题介绍了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的介绍都是委托只是封装一个方法,那委托能不能封装多个方法呢?因为生活中经常会听到, ...
- 方法字段[C# 基础知识系列]专题二:委托的本质论
首先声明,我是一个菜鸟.一下文章中出现技术误导情况盖不负责 引言: 上一个专题已和大家分享了我懂得的——C#中为什么须要委托,专题中简略介绍了下委托是什么以及委托简略的应用的,在这个专题中将对委托做进 ...
- [C# 基础知识系列]专题二:委托的本质论 (转载)
引言: 上一个专题已经和大家分享了我理解的——C#中为什么需要委托,专题中简单介绍了下委托是什么以及委托简单的应用的,在这个专题中将对委托做进一步的介绍的,本专题主要对委本质和委托链进行讨论. 一.委 ...
随机推荐
- MVC 4 结合jquery.uploadify 上传实例
前言:由于今天公司源代码服务瘫痪,没法编写代码,利用这个有限的时间,做了一个小小的 基于MVC的图片上传demo,貌似近些年来MVC十分火爆,相关的demo也数不胜数,小弟就在这里打着MVC的旗子,狐 ...
- 限制ITEM读取其它物料的物料描述
应用 Oracle Purchasing 层 Level Function 函数名 Funcgtion Name CUXPOXPOEPO 表单名 Form Name POXPOEPO 说明 Des ...
- poj1656---数黑格子
题意:有white,black,test操作 black将给定范围涂黑,white将给定范围涂白,test将给定范围的黑格子数出来并且输出 思路:无论哪个操作格子范围都在 (x,y) (x+L-1 ...
- oracle查看所有表及字段
oracle表设计 http://blog.csdn.net/lanpy88/article/details/7580820 Oracle查看所有表和字段 获取表: select table_name ...
- openNebula libvirt-virsh attach disk device for kvm
1,新建文件硬盘 qemu-img create -f qcow2 testdisk.img 2G
- oracle11g ora-12514监听程序当前无法识别
环境:win7_x64 ,oracle11g 描写叙述:1第一天没问题,第二天就不能连接: 2:pl sql developer连接工具,自己安装的oracle数据库,又装了client 3:装了or ...
- Lambda表达式图解
internal delegate int MyDel(int x); public class Lambda { ; };//匿名方法 ; };//Lambda表达式 ; };//Lambda表达式 ...
- 响应式(css_media)
开始研究响应式web设计,CSS3 Media Queries是入门. Media Queries,其作用就是允许添加表达式用以确定媒体的环境情况,以此来应用不同的样式表.换句话说,其允许我们在不改变 ...
- jquery prop()方法 解决全选 不全选 反选 问题 解决执行一次不不能再执行问题
//1.如果通过prop()函数更改<input>和<button>元素的type属性,在多数浏览器上将会抛出一个错误,因为该属性一般不允许在后期更改.//如果使用prop() ...
- 指定hive输出格式
0.11版本以前: sed -e 's/\x01/|/g' file 0.11版本以后: insert overwrite local directory '/opt/aimcpro/libc/tes ...