基础巩固系列 (一)- 泛型(1)

1、泛型介绍

       泛型是自.net framework 2.0以来就支持的。

       泛型是类型安全的。

       拥有了泛型,就可以创造出独立于被包含类型的类和方法了。也可以理解为,泛型就像是一个模板,常常定义一些通用的算法,具体调用时再替换成实际的数据类型,提高了代码的可重用性。

 

2、泛型的优缺点

      ⑴性能

           泛型的一个主要优点就是性能。

           在解释性能为什么是泛型的主要优点之前,我们还需要了解两个概念:

           装箱:从值类型转换为引用类型。

           拆箱:从引用类型转换为值类型。

var list = new ArrayList();
list.Add(44); //从值类型 转换为 引用类型 即装箱操作
int i = (int)list[0];//从引用类型 转换为 值类型 即拆箱操作

    装箱和拆箱操作需要进行类型的转换,无疑增加了些操作的时间,对性能肯定也是有影响的,特别是对于大数据的类型转换操作。那么接下来看看泛型是怎么操作的吧。

//System.Collections.Generic 命名空间里面的List<T>在不使用对象,而是在使用时定义类型。
var list = new List<int>();
list.Add(44); //由于list在定义时使用了int类型,所以在此处添加int类型 不需要进行装箱操作
int i = list[0];//理由同上

    System.Collections.Generic 命名空间里面的List<T>类不使用对象,而是在使用时定义类型。

  ⑵类型安全

    泛型的另外一个特性是类型安全。看以下代码:

//自定义类型
class myclass
{
     //此处省略
}

var list = new ArrayList();
list.Add(1);//添加 整型对象
list.Add("黑色街角");//添加 字符串对象
list.Add(new myclass());//添加 自定义对象

    对应ArrayList.Add(object value)方法,我们可以看到其参数为object类型对象,而object类是所有类的的基类,所有可以ArrayList.Add(object value)方法的参数可以是任意类型,以上运行也是这样的情况,但是对于下面这个呢?

//接上面代码 我们循环输出lis里面包含的t对象
foreach (int i in list)
{
        Console.Write(i);
}

     我想结果可想而知,肯定是会报错的。因为字符串类型和以上的自定义类型是不可能转换为int型类型的。

  

    那么接下来,我们看看泛型吧。

//泛型类型中已经定义了允许使用的类型为int类型
var list = new List<int>();
list.Add(1);//添加 int类型 是允许类型所以没有问题
list.Add("黑色街角");//添加 字符串对象 均会报错
list.Add(new myclass());//添加 自定义对象 均会报错

 

     因为泛型类型在初始化的时候,就已经定义了允许使用的类型为int类型,而且你在调用list.Add方法的时候,聪明的你会发现里面的参数为(int item),所以这从根本上统一了类型,在后续的循环输出也就没有问题了。这也就是泛型的类型安全。

  ⑶二进制代码的重用

    泛型允许很好的重用二进制代码。泛型类可以定义一次,并且可以使用不同的类型实例化。

    例如:using System.Collections.Generic 命名空间里面的泛型类 List<T>类

var list = new List<int>();//int类型 实例化
list.Add(1);

var stringlist = new List<string>();//字符串对象 实例化
stringlist.Add("黑色街角");

var myclasslist = new List<myclass>();//自定义对象 实例化
myclasslist.Add(new myclass());

     泛型类型可以在一种语言中定义,在任何.NET语言中使用。

  ⑷代码的扩展

    因为泛型类的定义会放在程序集中,所以用特定类型实例化泛型类不会再IL代码中复制这些类。但是,在JIT编译器把泛型类编译为本地代码时,会给每个值类型创建一个新类。引用类型共享同一个本地类的所有相同的实现代码。这是因为引用类型在实例化的泛型类中只需要4个字节的内存地址(32位操作系统),就可以引用一个引用类型。值类型包含在实例化的泛型类型的内存中,同时因为每个值类型对内存的要求有所不同,所以要为每个值类型实例化一个新类。

 

3、泛型的命名约定

  泛型的命名规则:

    泛型类型的名称用字母T作为前缀

    如果没有什么特殊的要求,泛型类型允许用任意类型代替,且只使用一个泛型类型,就可以用字母T作为泛型类型的名称。

public class List<T> { }

public class LinkedList<T> { }

 

    如果泛型类型有特定的要求(例如:它必须实现一个接口或者派生自基类),或者使用两个或多个泛型类型,就应该给泛型类型使用描述性的名称。

public delegate void EventHander<TEventArags>(object sender,TEventArags e);

public delegate Toutput Convert<Tinput,Toutput>(Tinput from);

public class SortedList<Tkey, Tvalue> { }

 

posted @ 2013-04-12 00:28  黑色街角  阅读(311)  评论(0编辑  收藏  举报