Understanding Generic Type, 理解泛型

什么是泛型

所谓泛型,就是指类型可以为任意. 最常用的泛型当然是用于创建集合了.

   1: List<int> list = new List<int>();   
   2: list.Add(1);  

为什么要用泛型?

这个问题可以分为几个分支, 我们一个一个来思考

  • 泛型跟传统的集合类比较有什么优势

  • a. 效率好,
  • 因为集合类(以ArrayList为例)对于所有对象的操作采用object作为对象
       1: ArrayList arrayList = new ArrayList();   
       2: arrayList.Add(12);   
       3: arrayList.Add("hello arraylist");  
     
  • 如上面的代码所示,他们在操作时既可以使用值类型,也可以是String, 因为他们都会向上转型为Object, 这样存在一定的性能损失,但是这是不是说泛型做集合性能就比ArrayList好呢? 请看这里
  • b. 类型确定
     

  •    1: int result = 0;        
       2: foreach (int i in list)        
       3: {              
       4:     result +=i;        
       5: }
     
  • 我们可以对泛型进行操作,对于ArrayList,我们则不那么方便了, 而且这样对于ArrayList这样书写也不会提示错误,然而在运行时则会出错。为程序的稳健性带来了隐患
       1: foreach (int i in array)   
       2: {   
       3:      result += i;   
       4: }  
  •  

    c. 代码重用

  • 过去,我们如果要定义一个强类型的集合,最常见的办法是继承自ICollection
       1: public class StrongTypeCollection : ICollection   
       2: {
       3:     public void Add() { // TODO:: Implement this }   
       4:       
       5:    // Other Methods To Override   
       6: }
  • 而现在我们使用IList<int> myCollection = new List<int>(int capbility); 就好再例如,我们可以使用
   1: public class MyClass : IComparable<int>, IComparable<double>
   2: {    
   3: }
泛型的用途

1. 集合类定义, 2. 泛型类型, 3. 泛型方法 4. 泛型代理

但之前,让我们先来看看泛型的使用限定,即泛型的约束。泛型的约束分为5种

值类型约束 class MyClass<T> where T : struct
引用类型约束 class MyClass<T> where T : class
接口类型约束 class MyClass<T> where T : IComparable<int>
基类约束(只有继承自BaseClass的子类才能成为改泛型的类型) class MyClass<T> where T : BaseClass
无参构造函数约束 class MyClass<T> where T : new()
当有多种类型的时候,new()只能放在最后
class MyClass<T> where T : class, new()

上面的例子都是一个类型的泛型,在.Net中可以定义多个类型

   1: // 定义多个类型
   2: public class MyClass<U, T>
   3: // 定义多个类型并确定类型的约束
   4: public class MyClass<U, T>
   5:                 where U : struct                               
   6:                 where T : class, new()
   7: // 确定类型之间的关系
   8: public class MyClass<U, T> where U : T

最后一行代码,所代表的关系是U必须继承自T, 见上面表格中的基类约束

关于上面的三种用法,我们最后分别给出一个例子

集合类定义

   1: IList<MyStruct> list = new List<MyStruct>();

泛型类型

   1: public class MyItem : IComparable<MyItem>
   2: {
   3:     public int CompareTo(MyItem item)
   4:     {
   5:         return this.Value.CompareTo( item.Value);
   6:     }
   7:  
   8:     public int Value {get;set;}
   9: }

泛型方法

   1: using System;
   2: using System.Collections.Generic;
   3: public class MyClass
   4: {
   5:     public static void Main()
   6:     {
   7:         MyGeneric my = new MyGeneric();
   8:         my.Run<double>(3);
   9:         
  10:         // The Type Must be the concerate generic type
  11:         // my.Run<double>(new Random());
  12:         
  13:         Console.Read();
  14:     }        
  15: }
  16: public class MyGeneric
  17: {
  18:     public void Run<T>(T t) where T : struct
  19:     {
  20:         Console.WriteLine("The Value Here Is {0}", t);
  21:     }
  22: }

泛型代理

   1: public delegate void MyAction<T>(T t); // Define the Type
   2: public event MyAction<string> OnActing; // Define The Event Instance
   3:  
   4: public void Output(string message) 
   5: {
   6:     Console.WriteLine(message);
   7: }
   8:     
   9: public void TestGenericDelegate()
  10: {
  11:     OnActing += Output; // Register A Event
  12:     OnActing("Hello, Generic Methods");     // Call The Event    
  13: }

还有几个特性为.Net泛型的小点心也不错哦

1. default(T) : 给泛型确定类型默认值, 引用类型为NULL,值类型为默认值,如int为0

2. 比较大小

   1: public class MyClass<T>
   2: {
   3:     public T Value {get;set;}
   4:     public int CompareTo(T t)
   5:     {    
   6:         return this.Value - t,Value; // Wrong
   7:     }
   8: }
   9:  
  10: public class MyClass<T> where T : IComapreable<T>
  11: {
  12:     public T Value {get;set;}
  13:     public int CompareTo(T t)
  14:     {    
  15:         return this.Value.CompareTo(t,Value);  // Correct
  16:     }
  17: }

3. 反射中对于泛型的特殊处理,反射中对于泛型采用特殊处理,点击这里查看

4. 泛型类之间不共享静态成员,查看详细: Generic Types Don't Share Static Members

参考:

http://msdn.microsoft.com/en-us/library/512aeb7t.aspx

Generic Types Don't Share Static Members

本博客内所有文章属于创作共享,您可以自由转载,摘抄,修改成您自己的版本,然而,如果您要将本文作为商业之用,请联系作者,谢谢合作。

posted on 2008-10-10 09:45  xwang  阅读(597)  评论(0编辑  收藏  举报

导航