1. 程式人生 > >掌握C#自定義泛型類:從初始化說起

掌握C#自定義泛型類:從初始化說起

C#自定義泛型類用得最廣泛,就是集合(Collection)中。實際上,泛型的產生其中一個原因就是為了解決原來集合類中元素的裝箱和拆箱問題(如果對裝箱和拆箱概念不明,請百度搜索)。由於泛型的使用,使得集合內所有元素都屬於同一類,這就把型別不同的隱患消滅在編譯階段——如果型別不對,則編譯錯誤。

這裡只討論C#自定義泛型類。基本自定義如下:

  1. publicclass MyGeneric < T>  
  2. ...{  
  3. private T member;  
  4. publicvoid Method (T obj)  
  5.     ...{  
  6.     }  

這裡,定義了一個泛型類,其中的T作為一個類,可以在定義的類中使用。當然,要定義多個泛型類,也沒有問題。

  1. publicclass MyGeneric < TKey, TValue>  
  2. ...{  
  3. private TKey key;  
  4. private TValue value;  
  5. publicvoid Method (TKey k, TValue v)  
  6.      ...{  
  7.      }  
  8. }  

泛型的初始化:泛型是需要進行初始化的。使用T doc = default(T)以後,系統會自動為泛型進行初始化。

限制:如果我們知道,這個將要傳入的泛型類T,必定具有某些的屬性,那麼我們就可以在MyGeneric< T>中使用T的這些屬性。這一點,是通過interface來實現的。

  1. // 先定義一個interface
  2. publicinterface IDocument  
  3. ...{  
  4. string Title ...{get;}  
  5. string Content ...{get;}  
  6. }  
  7. // 讓範型類T實現這個interface
  8. publicclass MyGeneric < T>  
  9. where T : IDocument  
  10. ...{  
  11. publicvoid Method(T v)  
  12.      ...{  
  13.           Console.WriteLine(v.Title);  
  14.      }  
  15. }  
  16. // 傳入的類也必須實現interface
  17. publicclass
     Document : IDocument  
  18. ...{  
  19. ......  
  20. }  
  21. // 使用這個泛型
  22. MyGeneric< Document> doc = new MyGeneric< Document>(); 

泛型方法:我們同樣可以定義泛型的方法

  1. void Swap< T> (ref T x, ref T y)  
  2. ...{  
  3. T temp = x;  
  4. x = y;  
  5. y = temp;  
  6. }  

泛型代理(Generic Delegate):既然能夠定義泛型方法,自然也可以定義泛型代理

  1. publicdelegatevoid delegateSample < T> (ref T x, ref T y)  
  2. privatevoid Swap (ref T x, ref T y)  
  3. ...{  
  4.     T temp = x;  
  5.     x = y;  
  6.     y = temp;  
  7. }  
  8. // 呼叫
  9. publicvoid Run()  
  10. ...{  
  11. int i,j;  
  12.    i = 3;  
  13.    j = 5;  
  14.    delegateSample< int> sample = new delegateSample< int> (Swap);  
  15.    sample(i, j);  

設定可空值型別:一般來說,值型別的變數是非空的。但是,Nullable< T>可以解決這個問題。

  1. Nullable< int> x;   // 這樣就設定了一個可空的整數變數x
  2. x = 4;  
  3. x += 3;  
  4. if (x.HasValue)   // 使用HasValue屬性來檢查x是否為空
  5. ...{ Console.WriteLine ("x="+x.ToString());  
  6. }  
  7. x = null;    // 可設空值

使用ArraySegment< T>來獲得陣列的一部分。如果要使用一個數組的部分元素,直接使用ArraySegment來圈定不失為一個不錯的辦法。

  1. int[] arr = ...{1, 2, 3, 4, 5, 6, 7, 8, 9};  
  2. // 第一個引數是傳遞陣列,第二個引數是起始段在陣列內的偏移,第三個引數是要取連續多少個數
  3. ArraySegment< int> segment = new ArraySegment< int>(arr, 2, 3);  // (array, offset, count) 
  4. for (int i = segment.Offset; i< = segment.Offset + segment.Count; i++)  
  5. ...{  
  6.    Console.WriteLine(segment.Array[i]);    // 使用Array屬性來訪問傳遞的陣列

在例子中,通過將Offset屬性和Count屬性設定為不同的值,可以達到訪問不同段的目的。

以上就是C#自定義泛型類的用法介紹。