泛型型別(.NET 指南)
泛型型別概述
在 .NET 中,開發人員隨時會使用泛型,有時隱式使用,有時顯式使用。 在 .NET
中使用 LINQ
時,你是否曾經注意到,使用的正是 IEnumerable<T>
? 或者,你是否曾經看到過有關使用實體框架來與資料庫通訊的“泛型儲存庫”線上示例,其中的大多數方法返回 IQueryable
? 你可能很想知道,這些示例中的 T
是什麼意思,為什麼要使用它?
泛型在 .NET Framework 2.0
中首次引入,它本質上是一個“程式碼模板”,可讓開發人員定義型別安全資料結構,無需處理實際資料型別。 例如,List<T>
是一個可以宣告的泛型集合,可與 List<int>
、List<string>
或 List<Person>
等任何型別結合使用。
為方便理解泛型的作用,讓我們看看新增泛型之前和之後的一個特定類:ArrayList
。 在 .NET Framework 1.0
中,ArrayList
元素屬於 Object
型別。 這意味著新增的任何元素都會以靜默方式轉換為 Object。 從列表讀取元素時,會發生相同的情況。 此過程稱為裝箱和取消裝箱,它會影響效能。 但更重要的是,在編譯時無法確定列表中的資料型別。 這就使得某些程式碼不太可靠。 泛型解決了此問題,它可以定義每個列表例項將要包含的資料型別。 例如,只能將整數新增到 List<int>
,只能將人員新增到 List<Person>
。
泛型還可以在執行時使用。 這意味著,執行時知道你要使用的資料結構型別,並可以更高效地將資料結構儲存在記憶體中。
下面的示例是一個小程式,演示了在執行時如何有效地瞭解資料結構型別:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace GenericsExample {
class Program {
static void Main(string[] args) {
//泛型列表
List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
//非泛型列表
ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
//泛型列表排序的計時器
Stopwatch s = Stopwatch.StartNew();
ListGeneric.Sort();
s.Stop();
Console.WriteLine($"Generic Sort: {ListGeneric} \n Time taken: {s.Elapsed.TotalMilliseconds}ms");
//非泛型列表排序的計時器
Stopwatch s2 = Stopwatch.StartNew();
ListNonGeneric.Sort();
s2.Stop();
Console.WriteLine($"Non-Generic Sort: {ListNonGeneric} \n Time taken: {s2.Elapsed.TotalMilliseconds}ms");
Console.ReadLine();
}
}
}
此程式將生成類似下面的輸出:
Generic Sort: System.Collections.Generic.List`1[System.Int32]
Time taken: 0.0034ms
Non-Generic Sort: System.Collections.ArrayList
Time taken: 0.2592ms
在此處可以看到的第一個優點是,泛型列表的排序比非泛型列表要快得多。 還可以看到,泛型列表的型別是不同的 ([System.Int32]
),而非泛型列表的型別已通用化。 由於執行時知道泛型 List<int>
的型別是 Int32
,因此可以將列表元素儲存在記憶體中的基礎整數陣列內;而非泛型 ArrayList
必須將每個列表元素強制轉換為物件。 如本示例中所示,多餘的強制轉換會佔用時間,降低列表排序的速度。
執行時知道泛型型別的另一個優點是可以改善除錯體驗。 在 C#
中除錯泛型時,可以知道資料結構中每個元素的型別。 如果不使用泛型,則無從知道每個元素的型別是什麼。
相關文章
- 【java】【泛型】泛型geneticJava泛型
- 型別 VS 泛型型別泛型
- TypeScript 泛型型別TypeScript泛型型別
- 泛型類、泛型方法、型別萬用字元的使用泛型型別字元
- Java™ 教程(泛型原始型別)Java泛型型別
- 型別與泛型標記型別泛型
- Scala 泛型型別和方法泛型型別
- Java泛型與型別擦除Java泛型型別
- .NET泛型解析(上)泛型
- .NET泛型解析(下)泛型
- NET 2.0中泛型泛型
- Java泛型型別擦除問題Java泛型型別
- TypeScript 基本型別和泛型的使用TypeScript型別泛型
- Java泛型知識點:泛型類、泛型介面和泛型方法Java泛型
- C# 泛型 引用型別約束 值型別約束C#泛型型別
- 【科普】.NET6 泛型泛型
- 泛型類、泛型方法及泛型應用泛型
- Java 泛型,你瞭解型別擦除嗎?Java泛型型別
- 【原創】【自制系列】自制stack型別(泛型)型別泛型
- java中泛型之型別萬用字元(?)Java泛型型別字元
- 泛型作為返回型別的寫法泛型型別
- Java中建立泛型型別的例項Java泛型型別
- 泛型類和泛型方法泛型
- java泛型之泛型方法。Java泛型
- 泛型--泛型萬用字元和泛型的上下限泛型字元
- .net原始碼分析 – Dictionary泛型原始碼泛型
- rust trait 關聯型別和泛型的區別RustAI型別泛型
- TypeScript 泛型介面和泛型類TypeScript泛型
- Go 泛型之泛型約束Go泛型
- java泛型之泛型陣列。Java泛型陣列
- C# 泛型集合的自定義型別排序C#泛型型別排序
- JAVA基礎之九-泛型(通用型別)Java泛型型別
- C#學習 [型別系統] 泛型(16)C#型別泛型
- rust學習十一.1、泛型(通用型別)Rust泛型型別
- 泛型泛型
- Go泛型草案設計簡明指南Go泛型
- Go中泛型和反射比較指南Go泛型反射
- .net原始碼分析 - ConcurrentDictionary泛型原始碼泛型