程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 詳解C#中的泛型和編程中應用泛型的長處

詳解C#中的泛型和編程中應用泛型的長處

編輯:C#入門知識

詳解C#中的泛型和編程中應用泛型的長處。本站提示廣大學習愛好者:(詳解C#中的泛型和編程中應用泛型的長處)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C#中的泛型和編程中應用泛型的長處正文


2.0 版 C# 說話和公共說話運轉時 (CLR) 中增長了泛型。泛型將類型參數的概念引入 .NET Framework,類型參數使得設計以下類和辦法成為能夠:這些類和辦法將一個或多個類型的指定推延到客戶端代碼聲明並實例化該類或辦法的時刻。例如,經由過程應用泛型類型參數 T,您可以編寫其他客戶端代碼可以或許應用的單個類,而不致引入運轉時強迫轉換或裝箱操作的本錢或風險,以下所示:

// Declare the generic class.
public class GenericList<T>
{
  void Add(T input) { }
}
class TestGenericList
{
  private class ExampleClass { }
  static void Main()
  {
    // Declare a list of type int.
    GenericList<int> list1 = new GenericList<int>();

    // Declare a list of type string.
    GenericList<string> list2 = new GenericList<string>();

    // Declare a list of type ExampleClass.
    GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
  }
}

泛型概述
應用泛型類型可以最年夜限制地重用代碼、掩護類型的平安和進步機能。
泛型最多見的用處是創立聚集類。
.NET Framework 類庫在 System.Collections.Generic 定名空間中包括幾個新的泛型聚集類。應盡量地應用這些類來取代通俗的類,如 System.Collections 定名空間中的 ArrayList。
您可以創立本身的泛型接口、泛型類、泛型辦法、泛型事宜和泛型拜托。
可以對泛型類停止束縛以拜訪特定命據類型的辦法。
關於泛型數據類型中應用的類型的信息可在運轉時經由過程應用反射獲得。

泛型類和泛型辦法同時具有可重用性、類型平安和效力,這長短泛型類和非泛型辦法沒法具有的。泛型平日用與聚集和感化於聚集的辦法一路應用。.NET Framework 2.0 版類庫供給一個新的定名空間 System.Collections.Generic,個中包括幾個新的基於泛型的聚集類。建議面向 .NET Framework 2.0 及更高版本的一切運用法式都應用新的泛型聚集類,而不要應用舊的非泛型聚集類如 ArrayList。

固然,也能夠創立自界說泛型類型和辦法,以供給本身的通用處理計劃,設計類型平安的高效形式。上面的代碼示例演示一個用於演示用處的簡略泛型鏈接列表類。(年夜多半情形下,應應用 .NET Framework 類庫供給的 List<T> 類,而不是自行創立類。)在平日應用詳細類型來指導列表中存儲的項的類型的場所,可以使用類型參數 T。其應用辦法以下:
在 AddHead 辦法中作為辦法參數的類型。
在 Node 嵌套類中作為公共辦法 GetNext 和 Data 屬性的前往類型。
在嵌套類中作為公有成員數據的類型。
留意,T 可用於 Node 嵌套類。假如應用詳細類型實例化 GenericList<T>(例如,作為 GenericList<int>),則一切的 T 都將被調換為 int。

// type parameter T in angle brackets
public class GenericList<T> 
{
  // The nested class is also generic on T.
  private class Node
  {
    // T used in non-generic constructor.
    public Node(T t)
    {
      next = null;
      data = t;
    }

    private Node next;
    public Node Next
    {
      get { return next; }
      set { next = value; }
    }

    // T as private member data type.
    private T data;

    // T as return type of property.
    public T Data 
    {
      get { return data; }
      set { data = value; }
    }
  }

  private Node head;

  // constructor
  public GenericList() 
  {
    head = null;
  }

  // T as method parameter type:
  public void AddHead(T t) 
  {
    Node n = new Node(t);
    n.Next = head;
    head = n;
  }

  public IEnumerator<T> GetEnumerator()
  {
    Node current = head;

    while (current != null)
    {
      yield return current.Data;
      current = current.Next;
    }
  }
}

上面的代碼示例演示客戶端代碼若何應用泛型 GenericList<T> 類來創立整數列表。只需更改類型參數,便可便利地修正上面的代碼示例,創立字符串或任何其他自界說類型的列表:

class TestGenericList
{
  static void Main()
  {
    // int is the type argument
    GenericList<int> list = new GenericList<int>();

    for (int x = 0; x < 10; x++)
    {
      list.AddHead(x);
    }

    foreach (int i in list)
    {
      System.Console.Write(i + " ");
    }
    System.Console.WriteLine("\nDone");
  }
}

泛型的長處
在公共說話運轉時和 C# 說話的晚期版本中,通用化是經由過程在類型與通用基類型 Object 之間停止強迫轉換來完成的,泛型供給了針對這類限制的處理計劃。經由過程創立泛型類,您可以創立一個在編譯時類型平安的聚集。
應用非泛型聚集類的限制可以經由過程編寫一小段法式來演示,該法式應用 .NET Framework 類庫中的 ArrayList 聚集類。 ArrayList 是一個應用起來異常便利的聚集類,無需停止修正便可用來存儲任何援用或值類型。

// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);

System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");

但這類便利是須要支付價值的。添加到 ArrayList 中的任何援用或值類型都將隱式地向上強迫轉換為 Object。假如項是值類型,則必需在將其添加到列表中時停止裝箱操作,在檢索時停止撤消裝箱操作。強迫轉換和裝箱和撤消裝箱操作都邑下降機能;在必需對年夜型聚集停止輪回拜訪的情形下,裝箱和撤消裝箱的影響異常顯著。
另外一個限制是缺乏編譯時類型檢討;由於 ArrayList 會將一切項都強迫轉換為 Object,所以在編譯時沒法避免客戶端代碼履行相似以下的操作:

System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");

int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
  t += x;
}

雖然將字符串和 ints 組合在一個 ArrayList 中的做法在創立異類聚集時是完整可接收的,而且有時須要成心為之,但這類做法極可能發生編程毛病,而且直到運轉時能力檢測到此毛病。
在 C# 說話的 1.0 和 1.1 版本中,只能經由過程編寫本身的特定於類型的聚集來防止 .NET Framework 基類庫聚集類中的通用代碼的風險。固然,因為此類弗成對多個數據類型重用,是以將損失通用化的長處,而且您必需對要存儲的每一個類型從新編寫該類。
ArrayList 和其他類似類真正須要的是:客戶端代碼基於每一個實例指定這些類要應用的詳細數據類型的方法。如許將不再須要向上強迫轉換為 T:System.Object,同時,也使得編譯器可以停止類型檢討。換句話說,ArrayList 須要一個類型參數。這恰是泛型所能供給的。在 N:System.Collections.Generic 定名空間的泛型 List<T> 聚集中,向聚集添加項的操作相似於以下情勢:

// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();

// No boxing, no casting:
list1.Add(3);

// Compile-time error:
// list1.Add("It is raining in Redmond.");

關於客戶端代碼,與 ArrayList 比擬,應用 List<T> 時添加的獨一語法是聲明和實例化中的類型參數。固然這類方法略微增長了編碼的龐雜性,但利益是您可以創立一個比 ArrayList 更平安而且速度更快的列表,關於列表項是值類型的情形尤其如斯。

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