c#泛型

  

一、泛型

假设我要写个公用的输出传入参数的方法(不用泛型),因为万物皆对象的理由,我先定义一个方法显示(对象obj),如下面所示:

<>之前,,,,,,,,public  static  void 显示(object  obj)   ,,,,,,,{   ,,,,,,,,,,,Console.WriteLine (obj.ToString ());   ,,,,,,,}

执行这个方法

<>之前,,,,,,,,,,,,int 小姐:=,1,,,//装箱   ,,,,,,,,,,,显示(i);

如果传入的是值类型,值类型转换为引用类型,我们知道会发生装箱,这是对性能的损害,想想如果是个集合,就得多次执行装箱,拆箱操作。如ArrayList类,ArrayList储存对象,添加()方法定义为需要把一个对象作为参数,如果传入的值类型,就得装箱,在读取ArrayList中的值时,又得进行拆箱,如下面代码所示:

 c#泛型

<>之前,,,,,,,,,,,,var  list =, new  ArrayList ();   ,,,,,,,,,,,list.Add(1),,//装箱      ,,,,,,,,,,,foreach  (int 小姐:拷贝列表)   ,,,,,,,,,,,{   ,,,,,,,,,,,,,,,Console.WriteLine (i),,//拆箱   ,,,,,,,,,,,}

 c#泛型

如果使用泛型,就不会出现这样的问题了,我们使用List类来改造上面代码:

 c#泛型

<>之前,,,,,,,,,,,,var  list =, new  List ();   ,,,,,,,,,,,list.Add (1),,      ,,,,,,,,,,,foreach  (int 小姐:拷贝列表)   ,,,,,,,,,,,{   ,,,,,,,,,,,,,,,Console.WriteLine(我),   ,,,,,,,,,,,}

 c#泛型

这里就不存在装箱和拆箱了,所以我们在使用集合的时候,尽量使用泛型集合,不要使用非泛型集合。

二、类型安全

在上面ArrayList类中,添加参数时,可以添加任何对象,比如上面的例子,如果在添加整数类型后再添加引用类型,这么做在编译时是没有任何问题,但是在foreach语句使用整数类型迭代的时候就会报错。

 c#泛型

<>之前,,,,,,,,,,,,var  list =, new  ArrayList ();   ,,,,,,,,,,,list.Add(1),,//装箱   ,,,,,,,,,,,list.Add(“字符串”),,,,,,,,,,,,,foreach  (int 小姐:拷贝列表)   ,,,,,,,,,,,{   ,,,,,,,,,,,,,,,Console.WriteLine(我);   ,,,,,,,,,,,}

 c#泛型

这时候就会报InvalidCastException的异常。

如果使用泛型集合List的时候去重写上面的代码,在编译的时候就会报错。所以这个地方我们就能知道,泛型是在编译时就已经执行了,所以系统运行时我们时没有装箱拆箱的系统开销,而非泛型是在运行时执行的,所以可能导致异常发生;

三、创建泛型类和泛型方法

泛型方法,从我最先第一个例子显示(对象),,采用泛型来重写,定义为Show (T);

<>之前,,,,,,,,public  static  void  Show (T  obj)   ,,,,,,,{   ,,,,,,,,,,,Console.WriteLine (obj.ToString ());   ,,,,,,,}

,泛型类,如公共类List {}

3.1命名约定

<李>

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

<李>

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

<李>

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

,,,公众委托无效EventHandler(对象发送方,TEventArgs e);

,,,公众委托TOutput Convert (TInput输入),

,,,公共类SortedList {};

3.2默认值

,,null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

c#泛型