引言:

前面专题主要介绍了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# 基础知识系列]专题六:泛型基础篇——为什么引入泛型的更多相关文章

  1. [C# 基础知识系列]专题九: 深入理解泛型可变性

    引言: 在C# 2.0中泛型并不支持可变性的(可变性指的就是协变性和逆变性),我们知道在面向对象的继承中就具有可变性,当方法声明返回类型为Stream,我们可以在实现中返回一个FileStream的类 ...

  2. [C# 基础知识系列]专题七: 泛型深入理解(一) (转载)

    引言: 在上一个专题中介绍了C#2.0 中引入泛型的原因以及有了泛型后所带来的好处,然而上一专题相当于是介绍了泛型的一些基本知识的,对于泛型的性能为什么会比非泛型的性能高却没有给出理由,所以在这个专题 ...

  3. [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托

    转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...

  4. [C# 基础知识系列]专题八: 深入理解泛型(二)

    引言: 本专题主要是承接上一个专题要继续介绍泛型的其他内容,这里就不多说了,就直接进入本专题的内容的. 一.类型推断 在我们写泛型代码的时候经常有大量的"<"和"& ...

  5. [C# 基础知识系列]专题十六:Linq介绍

    转自http://www.cnblogs.com/zhili/archive/2012/12/24/Linq.html 本专题概要: Linq是什么 使用Linq的好处在哪里 Linq的实际操作例子— ...

  6. [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)

    当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...

  7. [C# 基础知识系列]专题三:如何用委托包装多个方法——委托链 (转载)

    引言: 上一专题介绍了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的介绍都是委托只是封装一个方法,那委托能不能封装多个方法呢?因为生活中经常会听到, ...

  8. 方法字段[C# 基础知识系列]专题二:委托的本质论

    首先声明,我是一个菜鸟.一下文章中出现技术误导情况盖不负责 引言: 上一个专题已和大家分享了我懂得的——C#中为什么须要委托,专题中简略介绍了下委托是什么以及委托简略的应用的,在这个专题中将对委托做进 ...

  9. [C# 基础知识系列]专题二:委托的本质论 (转载)

    引言: 上一个专题已经和大家分享了我理解的——C#中为什么需要委托,专题中简单介绍了下委托是什么以及委托简单的应用的,在这个专题中将对委托做进一步的介绍的,本专题主要对委本质和委托链进行讨论. 一.委 ...

随机推荐

  1. python模块—urllib

    1. 网页操作 urllib.urlopen(url[,data[,proxies]]) 打开一个url,返回一个文件对象,然后可以进行类似文件对象操作 url:远程数据的路径,即网址 data:表示 ...

  2. Linux 如何打开端口

    举例: 开放10000端口的解决步骤如下: 1.修改/etc/sysconfig/iptables文件,增加如下一行: -A RH-Firewall-1-INPUT -m state --state ...

  3. 一款C++静态分析工具 —— CppDepend

    Wrote by mutouyun. (http://darkc.at/cppdepend/) 去年6月份的时候,CppDepend的一位技术社区经理(technical community mana ...

  4. Android 学习之 开源项目PullToRefresh的使用

    首先 下载 Android-PullToRefresh-master 下载地址  https://github.com/chrisbanes/Android-PullToRefresh 下载之后将其解 ...

  5. 转:web前端面试题合集 (Javascript相关)(js异步加载详解)

    1. HTTP协议的状态消息都有哪些? 1**:请求收到,继续处理2**:操作成功收到,分析.接受3**:完成此请求必须进一步处理4**:请求包含一个错误语法或不能完成5**:服务器执行一个完全有效请 ...

  6. nginx 通过rsyslog发日志 rsyslog服务器挂掉 日志丢失问题

    nginx 配置: user nginx; worker_processes 1; syslog local5 nginx-zjzc01; rsyslog 服务器收到的消息: -rw-r--r-- 1 ...

  7. qemu 调试(二)

    我见过最全的剖析QEMU原理的文章 qemu代码分析 qemu中ELF文件的加载 几个关键点,可以设计断点,观察. $ cat command.gdbset breakpoint pending on ...

  8. brief InformationTechnology theory of evolution

    信息技术进化论简述 无文化流氓帮帮主Ruiy Pk 清华土匪帮帮主YiC 1,按人机交互方式 命令行-->图形界面-->自然交互(语音+手控) Tips:命令行(IBM大型机,小型机+ S ...

  9. 值得赞扬的尝试与进步——CSDN开源夏令营第一印象

    注:写这篇文章时我并未參加CSDN开源夏令营,也不确定是否会參加以及是否能參加上. 欣闻CSDN举办了"CSDN开源夏令营"活动.第一感觉是CSDN作为活动的组织者是很值得称赞的. ...

  10. SQL学习之高级数据过滤

    一.高级数据过滤之IN操作符 IN 操作符用来指定条件范围,范围中的每个条件都可以进行匹配.IN取一组由逗号分隔.括在圆括号中的合法值.代码如下: select ItemId,ItemName,Che ...