首頁 後端開發 C#.Net教程 淺談C#泛型的用處

淺談C#泛型的用處

Dec 21, 2016 pm 02:48 PM

為什麼要使用C#泛型?

為了了解這個問題,我們先看下面的程式碼,程式碼省略了一些內容,但功能是實作一個棧,這個棧只能處理int資料型別:

public class Stack      { PRivate int[] m_item;          public int Pop(){...}          public void Push(int item){               this.m_item = new int[i];          }  } 以上碼執行的很好,但是,當我們需要一個堆疊來保存string類型時,該怎麼辦呢?很多人都會想到把上面的程式碼複製一份,把int改成string不就行了。當然,這樣做本身是沒有任何問題的,但一個優秀的程式是不會這樣做的,因為他想到若以後再需要long、Node類型的棧該怎麼做呢?還要再複製嗎?優秀的程式設計師會想到用一個通用的資料型別object來實現這個堆疊:

public class Stack      {          private      public void Push(object item){.. .}          public Stack(int i)          {             } 這個棧寫的不錯,他非常靈活,可以接收任何資料類型,可以說是一勞永逸。但全面地講,也不是沒有缺陷的,主要表現在:

當Stack處理值類型時,會出現裝箱、折箱操作,這將在託管堆上分配和回收大量的變量,若數據量大,則性能損失非常嚴重。 

在處理引用類型時,雖然沒有裝箱和折箱操作,但將用到資料型別的強制轉換操作,增加處理器的負擔。

在數據類型的強制轉換上還有更嚴重的問題(假設stack是Stack的一個實例):

Node1 x = new Node1();              stack.Push(x);           Node2 y = (Node2)stack. Pop(); 上面的程式碼在編譯時是完全沒問題的,但由於Push了一個Node1類型的數據,但在Pop時卻要求轉換為Node2類型,這將出現程式運行時的類型轉換異常,但卻逃離了編譯器的檢查。

針對object類型棧的問題,我們引入泛型,他可以優雅地解決這些問題。泛型用用一個通過的資料類型T來取代object,在類別實例化時指定T的類型,運行時(Runtime)自動編譯為本地程式碼,運行效率和程式碼品質都有很大提高,並且保證資料類型安全。

使用C#泛型

下面是用泛型來重寫上面的棧,用一個通用的資料型別T來作為一個佔位符,等待在實例化時用一個實際的型別來代替。讓我們來看看泛型的威力:

public class Stack      {          private T[] m_item    item){...}          public Stack(int i) {              this.m_item = new T[i];          this.m_item = new T[i];              }  } 類別的寫法不變,只是引入了通用資料類型T這個類別的呼叫方法:

//實例化只能保存int類型的類別  Stack a = new Stack(100);        a.Push(10);        a.Push("8888"); //這一行中只接收未接收,因為類別的編譯類型的資料        int x = a.Pop();  //實例化只能保存string類型的類別  Stack b = new Stack(100);  b.Push(10)    //此行編譯不通過,因為此行編譯只接收string類型的資料        b.Push("8888");  string y = b.Pop(); 這個類別和object實現的類別有截然不同的差異:

1. 他是類型安全的。實例化了int型別的棧,就不能處理string類型的數據,其他資料型別也一樣。

2.無需裝箱和折箱。這個類別在實例化時,按照所傳入的資料類型產生本地代碼,本地代碼資料類型已確定,所以無需裝箱和折箱。

3. 無需型別轉換。

理論知識:

所謂泛型:即透過參數化類型來實現在同一份程式碼上操作多種資料型別。泛型程式設計是一種程式設計範式,它利用「參數化類型」將類型抽象化,從而實現更靈活的複用。

C#泛型賦予了程式碼更強的型別安全,更好的複用,更高的效率,更清晰的限制。

C#泛型能力由CLR在運行時支持,區別於C++的編譯時模板機制,和java的編譯時的「搽拭法」。這使得泛型能力可以在各個支援CLR的語言之間進行無縫的互通。

C#泛型程式碼在被編譯為IL和元資料時,採用特殊的佔位符來表示泛型類型,並用專有的IL指令支援泛型運算。而真正的泛型實例化工作以「on-demand」的方式,發生在JIT編譯時。

C#泛型編譯機制如下:

第一輪編譯時,編譯器只為Stack類型產生「泛型版」的IL程式碼和元數據,並不進行泛型類型的實例化,T在中間只充當佔位符。

JIT編譯時,當JIT編譯器第一次遇到Stack時,將以int型別取代「泛型版」IL程式碼與元資料中的T -- 進行泛型類型的實例化。

CLR為所有類型參數為“引用類型”的泛型類型產生同一份代碼,但如果類型參數為“值類型”,對每一個不同的“值類型”,CLR將為其產生一份獨立的代碼。

C#泛型的幾個特點

如果實例化泛型類型的參數相同,那麼JIT編譯器會重複使用該類型,因此C#的動態泛型能力避免了C++靜態模板可能導致的程式碼膨脹的問題。

C#泛型類型攜帶有豐富的元數據,因此C#的泛型類型可以應用於強大的反射技術。

C#的泛型採用“基類、接口、構造器、值類型/引用類型”的約束方式來實現對類型參數的“顯示約束”,提高了類型安全的同時,也喪失了C++模板基於“簽名」的隱式約束所具有的高彈性。

C#泛型類別在編譯時,先生成中間程式碼IL,通用型別T只是一個佔位符。在實例化類別時,根據使用者指定的資料類型取代T並由即時編譯器(JIT)產生本地程式碼,這個本地程式碼中已經使用了實際的資料類型,等同於用實際類型寫的類,所以不同的封閉類別的本地代碼是不一樣的。依照這個原理,我們可以這樣認為:泛型類別的不同的封閉類別是分別不同的資料類型。

這樣泛型不僅更靈活,也同時將程式碼的簡單和提升到一個層次!不用再為具體不同的重載方法寫出具體的程式碼了!

C# 泛型是開發工具庫中的一個無價之寶。它們可以提高效能、類型安全性和質量,減少重複性的程式設計任務,簡化整體程式設計模型,而這一切都是透過優雅的、可讀性強的語法完成的。儘管 C# 泛型的根基是 C++ 模板,但 C# 透過提供編譯時安全性和支援將泛型提高到了一個新水平。 C# 利用了兩階段編譯、元資料以及諸如約束和一般方法之類的創新性的概念。毫無疑問,C# 的將來版本將繼續發展泛型,以便添加新的功能,並且將泛型擴展到諸如數據訪問或本地化之類的其他.NET Framework 領域.

 以上就是淺談C#泛型的用處的內容,更多相關內容請關注PHP中文網(www.php.cn)! 


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用 C# 的活動目錄 使用 C# 的活動目錄 Sep 03, 2024 pm 03:33 PM

使用 C# 的活動目錄

C# 中的存取修飾符 C# 中的存取修飾符 Sep 03, 2024 pm 03:24 PM

C# 中的存取修飾符

C# 中的隨機數產生器 C# 中的隨機數產生器 Sep 03, 2024 pm 03:34 PM

C# 中的隨機數產生器

C# 資料網格視圖 C# 資料網格視圖 Sep 03, 2024 pm 03:32 PM

C# 資料網格視圖

C# 字串讀取器 C# 字串讀取器 Sep 03, 2024 pm 03:23 PM

C# 字串讀取器

C# 中的模式 C# 中的模式 Sep 03, 2024 pm 03:33 PM

C# 中的模式

C# 字串編寫器 C# 字串編寫器 Sep 03, 2024 pm 03:23 PM

C# 字串編寫器

C# 中的二進位編寫器 C# 中的二進位編寫器 Sep 03, 2024 pm 03:22 PM

C# 中的二進位編寫器

See all articles