搜尋
首頁後端開發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
C#.NET與未來:適應新技術C#.NET與未來:適應新技術Apr 14, 2025 am 12:06 AM

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

c#.net適合您嗎?評估其適用性c#.net適合您嗎?評估其適用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案:提高您的專業知識C#.NET面試問題和答案:提高您的專業知識Apr 07, 2025 am 12:01 AM

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

使用C#.NET建築微服務:建築師實用指南使用C#.NET建築微服務:建築師實用指南Apr 06, 2025 am 12:08 AM

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。

See all articles

熱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.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境