程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 分析 C# 2.0 新特性 -- 范型(Generics)

分析 C# 2.0 新特性 -- 范型(Generics)

編輯:.NET實例教程
范型是提高面向對象程序多態性設計衍生的。
1,C# 多態性設計回顧和展望
在引入范型這個概念之前,回顧一下1.0或1.1中關於的Object類型的定義:
Object類型是.Net Framework中System.Object的一個別名,可以分配任何類型給Object類型的變量。
通過object類型的引入,實現了.Net對於面向對象程序多態設計。
因為Object本身是一個引用類型,是存放在Heap(堆)上的。對於其他引用類型和Object轉換很容易實現。
而值類型和Object類型轉換需要引入兩個用於object類型和值類型轉換概念boxing和unboxing.
(1)boxing 裝包
  將轉換一個值類型到Object類型,
  例如:int i = 1;            //存儲在棧上
        object o = (object) i;//存儲在堆上
  上面的代碼在IL中將會是box [mscorlib]System.Int32
 將Int32和1同時裝入一個Object對象中,結構如下:
 object[{Int32}-{1}];//前者表示boxing類型,後者表示其值
(2)unboxing 拆包
 將一個已裝包為Obect類型的值類型轉換回值類型
 操作分為兩部分組成:
 a,首先檢查是否轉換回的類型是裝包的類型,如果不是拋出一個InvalidCastException運行時錯誤.
 b,復制Object類型中的值到目標值類型變量;
 例如:
   int i = 1;
      object o = (object) i; //boxing
      int j = (int)o         //unboxing
      //double d = (double)o ,出現運行時錯誤
 
通過上面的可以看到在.Net Framework 1.0 中使用object對象設計的多態性比C++的template(一種基於類似宏的編
譯時替換)執行效率增加了大量的copy的開銷。所以在.Net Framewrok 2.0中引入范型來提高高面向對象程序多態性
設計。

2,范型概念和特點:
范型的設計是為了解決上面提到過的Object的多態性設計中的兩個問題:
(1),性能上面的,boxing和unboxing需要大量的復制開銷;
(2),安全性上面的,在上面一個例子看到了如果unboxing類型不同會拋出一個InvalidCastException異常;
范型的設計格式是使用<和>封閉其中一個范型參數,例如:
public class Stack<T>;
范型的實例化格式是使用需要使用的類型替換<和>封閉其中一個范型參數,例如:
Stack<char> char_Stack = new Stack<char>();
多范型類定義格式,在<和>封閉多個范型參數,例如:
class Node<K,T>
對於C++程序員,看上面關於范型的格式很快聯系到了ISO C++當中的Template;
的確兩者語法上面非常相似,但是兩者的多態性編譯和實現有很大不同.
在C++的Template編譯後,沒有編譯帶有Template的代碼.而是通過一種宏的方式進行的替換過程.
每次使用Template類型,編譯器都會生成一個對應的類型代碼.而不管是否個類型代碼已經使用過了.
在C#2.0中范型是在中間語言(IL)和公共語言運行時(CLR)支持的.
對於值類型:會在JIT編譯時候替換參數類型,如果存在以及編譯特定類型的機器代碼,將直接返回這段代碼.
這樣避免了在ISO C++中Template可能帶來代碼膨脹.
對於引用類型:會直接在JIT編譯時候替換參數類型.
理解C# 2.0范型是在實現是基於CLR支持的很重要啊,因為.Net的本質是和語言無關的.任何語言最後都是編譯為中
間語言,這樣基於IL和CLR支持的范型可以運用到所有基於CLR實現的語言,例如:Visual Basic 2005等等.
3,范型和其他類型執行效率對比例子
下面分別是使用Int,Object和范型構造的3個棧的類
 /// <summary>
 /// Int類型實現的棧
 /// </summary>
 class IntStack
 {
  private int[] data;
  private int current;
  private int length;
  public IntStack(int Length)
  {
   length = Length;
   current = 0;
   data = new int[length];
  }
  public int Top()
  {
   return data[current - 1];
  }
  public void Push(int Data)
  {
   if (current < length)
   {
    data[current++] = Data;
   }
  }
  public void Pop()
  {
   if (current > 0)
   {
    current--;
   }
  }
 }
 /// <summary>
 /// 范型的棧
 /// </summary>
 /// <typeparam name="T">范型</typeparam>
 class TemplateStack<T>
 {
  private int length;
  private int current;
  private T[] data;
  public TemplateStack(int Length)
  {
   current = 0;
   length = Length;
   data = new T[length];
  }
  public T Top()
 &nbsp;{
   return data[current - 1];
  }
  public void Push(T Data)
  {
   if (current < length)
   {
    data[current++] = Data;
   }
  }
  public void Pop()
  {
   if (current > 0)
   {
    current--;
   }
  }
 }
 /// <summary>
 /// Object的棧
 /// </summary>
 class ObjectStack
 {
  private object[] data;
  private int current;
  private int length;
  public ObjectStack(int Length)
  {
   length = Length;
; current = 0;
   data = new object[length];
  }
  public object Top()
  {
   return data[current-1];
  }
  public void Push(object Data)
  {
   if (current < length)
   {
    data[current++] = Data;
   }
  }
  public void Pop()
  {
   if (current > 0)
   {
    current--;
   }
  }
 }
通過測試直接使用Int的棧和范型構造Int棧的開銷接近.
而比較前面兩個Object每增加一次unboxig開銷是增加的2倍.

4,附錄.Net 2.0 Framework 范型容器列表:
Comparer<T>      Comparer   比較
Dictionary<K,T>     HashTable  hash表
LinkedList<T>         LinkList   鏈表
List<T>         &nbsp;     ArrayList  數組鏈表
Queue<T>              Queue    隊列
SortedDictionary<K,T> SortedList 排序鏈表
Stack<T>              Stack    棧
ICollection<T>  ICollection    容器接口
IComparable<T>  System.IComparable比較接口
IDictionary<K,T>  IDictionary    字典接口
IEnumerable<T>  IEnumerable    枚舉接口
IEnumerator<T>  IEnumerator    跌代接口
IList<T>  IList          鏈表接口
 
參考資料:
《Design and Implementation of Generics for the .Net Common Language Runtime》 
  ---Andrew Kennedy Don Syme (Microsoft Research, Cambridge, U.K.)
《An Introduction to C# Generics》
  ---Juval Lowy IDesign (MSDN Online)
《C# Programmer''s Reference》
  ---MSDN Library  (MSDN Online) 

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved