C# 泛型

泛型

泛型不是語法糖,而是由框架提供的一種便捷語法,首次出現在.NET 2.0中。

1. 泛型定義

  • 泛型:是一種程序特性,定義時不對類型做出明確的規定,使用時規定且不能改變。
  • 一般應用:泛型集合、泛型方法、泛型類、泛型委托。
    • 泛型方法:方法的返回值類型、參數類型定義成泛型類型。
    • 泛型集合:如List<T>Dictionary<K, V>,所在命名空間:System.Collections.Generic
    • 非泛型集合:ArrayListHashtable,所在命名空間:System.Collections。非泛型集合中可以添加任意類型,但對于數據本身來說,這是非常不安全的,并且存在裝箱和拆箱問題。
      • 裝箱:將值類型的元素放到集合中會被轉換成object類型。
      • 拆箱:將一個集合的元素取出來,但這個元素本身是值類型,必須進行強制類型轉換。
      • 弊端:如果存儲大量的數據,會影響性能。

2. 泛型賦值與約束

  • default關鍵字:主要用于直接的賦值,引用類型賦值為null,值類型給值默認值,如T a = default(T)
  • 泛型約束
    • where T1 : class // T1必須是引用類型。
    • where T2 : struct // T2必須是值類型。
    • where T3 : new() // 必須有一個無參構造方法。
    • where T4 : 接口 // 接口約束。
    • where T5 : 類名 // 基類約束。
  • 約束是可以疊加的,比單個基類更靈活的約束目標。
  • 由于泛型類型是不確定的,所以泛型類型在編譯階段無法直接轉換。可采用dynamic類,在運行動態解析對象類型。在編譯階段是不解析的,類型轉換不對,會在運行時報錯。

代碼示例

1. 代碼重用
public class GenericList<T>
{private T[] items;private int count;public GenericList(int capacity){items = new T[capacity];}public void Add(T item){if (count == items.Length){throw new IndexOutOfRangeException("List is full");}items[count] = item;count++;}// 其他方法...
}// 使用示例
var intList = new GenericList<int>(10);
intList.Add(1);
intList.Add(2);var stringList = new GenericList<string>(5);
stringList.Add("Hello");
stringList.Add("World");
2. 類型安全
// 使用泛型集合,無需擔心類型錯誤
List<int> intList = new List<int>();
intList.Add(1);
// intList.Add("string"); // 編譯錯誤,因為集合是 int 類型的
3. 性能優化
// 使用泛型集合避免了裝箱和拆箱操作
List<int> intList = new List<int>();
intList.Add(1);
int firstInt = intList[0]; // 直接訪問,無需拆箱// 相比之下,使用非泛型集合會有裝箱和拆箱開銷
ArrayList arrayList = new ArrayList();
arrayList.Add(1); // 裝箱
int firstValue = (int)arrayList[0]; // 拆箱
4. 減少代碼冗余
// 泛型類可以替代多個具有相似功能的類
Stack<int> intStack = new Stack<int>();
intStack.Push(1);
int topInt = intStack.Pop();Stack<string> stringStack = new Stack<string>();
stringStack.Push("Hello");
string topString = stringStack.Pop();
5. 擴展性
public interface IRepository<T>
{T Get(int id);void Add(T item);// 其他方法...
}public class ProductRepository : IRepository<Product>
{// 實現 IRepository<Product> 接口的方法
}IRepository<Product> productRepo = new ProductRepository();
Product product = productRepo.Get(1);
6. 泛型約束示例
public class GenericComparer<T> where T : IComparable<T>
{public int Compare(T x, T y){return x.CompareTo(y);}
}var comparer = new GenericComparer<int>();
int result = comparer.Compare(1, 2); // 返回 -1
7. 與集合框架的集成
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Dictionary<string, int> ages = new Dictionary<string, int>();
ages.Add("Alice", 30);
ages.Add("Bob", 25);var olderThan30 = ages.Where(entry => entry.Value > 30);
foreach (var pair in olderThan30)
{Console.WriteLine("{0} is {1} years old.", pair.Key, pair.Value);
}
8. 泛型委托示例
public delegate TResult GenericDelegate<T, TResult>(T arg);public class GenericClass
{public static int Double(int value){return value * 2;}
}GenericDelegate<int, int> del = GenericClass.Double;
int result = del(5); // 結果為 10

高級用法與技巧

泛型在反射中的應用
創建泛型類型的實例
using System;
using System.Reflection;public class GenericClass<T>
{public T Property { get; set; }public GenericClass(T property){Property = property;}
}class Program
{static void Main(){Type genericType = typeof(GenericClass<>);Type specificType = genericType.MakeGenericType(typeof(int));object instance = Activator.CreateInstance(specificType, 42);Console.WriteLine(((GenericClass<int>)instance).Property); // 輸出: 42}
}
調用泛型方法
using System;
using System.Reflection;public class GenericMethodsClass
{public void GenericMethod<T>(T param){Console.WriteLine(param);}
}class Program
{static void Main(){var genericMethodsClass = new GenericMethodsClass();MethodInfo genericMethod = typeof(GenericMethodsClass).GetMethod("GenericMethod");MethodInfo specificMethod = genericMethod.MakeGenericMethod(typeof(string));specificMethod.Invoke(genericMethodsClass, new object[] { "Hello, World!" }); // 輸出: Hello, World!}
}
協變和逆變
協變(Covariance)
using System;
using System.Collections.Generic;public class CovarianceExample
{public static void PrintValues<T>(IEnumerable<T> collection){foreach (var item in collection){Console.WriteLine(item);}}static void Main(){IEnumerable<string> strings = new List<string> { "A", "B", "C" };// 協變使得可以將IEnumerable<string>賦值給IEnumerable<object>IEnumerable<object> objects = strings;PrintValues(objects); // 輸出: A, B, C}
}
逆變(Contravariance)
using System;
using System.Collections.Generic;public class ContravarianceExample
{public static void Compare<T>(T first, T second, IComparer<T> comparer){if (comparer.Compare(first, second) > 0){Console.WriteLine($"{first} is greater than {second}.");}else{Console.WriteLine($"{first} is less than or equal to {second}.");}}static void Main(){// 逆變使得可以將IComparer<object>賦值給IComparer<string>IComparer<object> objectComparer = Comparer<object>.Default;IComparer<string> stringComparer = objectComparer;Compare("apple", "orange", stringComparer); // 輸出可能因默認比較器而異}
}

在這兩個例子中,協變允許我們將一個更具體的集合類型(如IEnumerable<string>)賦值給一個較不具體的類型(如IEnumerable<object>)。而逆變則允許我們將一個較不具體的比較器類型(如IComparer<object>)賦值給一個更具體的類型(如IComparer<string>)。這兩個特性在泛型編程中非常有用,因為它們提供了更大的靈活性和類型安全性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43395.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43395.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43395.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習——LR、?GBDT、?SVM、?CNN、?DNN、?RNN、?Word2Vec等模型的原理和應用

LR&#xff08;邏輯回歸&#xff09; 原理&#xff1a; 邏輯回歸模型&#xff08;Logistic Regression, LR&#xff09;是一種廣泛應用于分類問題的統計方法&#xff0c;尤其適用于二分類問題。其核心思想是通過Sigmoid函數將線性回歸模型的輸出映射到(0,1)區間&#xff0c;從…

【AI前沿】深度學習:神經網絡基礎

文章目錄 &#x1f4d1;引言一、神經元和感知器1.1 神經元的基本概念1.2 感知器模型 二、多層感知器&#xff08;MLP&#xff09;2.1 MLP的基本結構2.2 激活函數的重要性2.3 激活函數2.4 激活函數的選擇 三、小結 &#x1f4d1;引言 深度學習是現代人工智能的核心技術之一&…

kotlin Flow 學習指南 (三)最終篇

目錄 前言Flow生命周期StateFlow 替代LiveDataSharedFlow其他常見應用場景處理復雜、耗時邏輯存在依賴關系的接口請求組合多個接口的數據 Flow使用注意事項總結 前言 前面兩篇文章&#xff0c;介紹了Flow是什么&#xff0c;如何使用&#xff0c;以及相關的操作符進階&#xff…

如何挑選適合的需求池管理系統?10款優質工具分享

本文將分享10款優質需求池管理工具&#xff1a;PingCode、Worktile、Teambition、Epicor Kinetic、TAPD、SAP IBP、Logility、RELEX Solutions、JIRA、明道云。 在管理項目和產品需求時&#xff0c;正確的工具能夠大幅提高效率與透明度。如何從眾多需求池工具中選擇最適合團隊的…

第一節 SHELL腳本中的常用命令(2)

二,網絡管理命令nmcli 1.查看網卡 # 或者先用ip addr或ip a等查看網卡 ip a s 網卡名 ifconfig 網卡名 nmcil device show 網卡名 nmcil device status nmcil connection show 網卡名2.設置網卡 a)當網卡未被設置過時 設置dncp網絡工作模式 nmcil connection add con-name…

Rust編程-編寫自動化測試

編寫單元測試步驟&#xff1a; 1. 準備所需的數據 2. 調用需要測試的代碼 3. 斷言運行結果與我們所期望的一致 Rust的test元數據&#xff1a; #[cfg(test)]&#xff1a;是一個屬性宏&#xff08;attribute macro&#xff09;。用于控制特定的代碼段僅在測試環境中編譯…

自定義類型:聯合體

像結構體一樣&#xff0c;聯合體也是由一個或者多個成員組成&#xff0c;這些成員可以是不同的類型。 聯合體類型的聲明 編譯器只為最?的成員分配?夠的內存空間。聯合體的特點是所有成員共?同?塊內存空間。所以聯合體也叫&#xff1a;共?體。 輸出結果&#xff1a; 聯合體…

size_t 數據類型的好處

什么是size_t size_t 類型在不同的平臺上對應不同的底層整數類型&#xff0c;具體取決于平臺的指針大小。size_t 主要用于表示大小和長度&#xff0c;如數組的元素數量、緩沖區的大小等&#xff0c;它的設計目的是為了匹配指針的大小&#xff0c;以避免類型不匹配引起的錯誤。…

代碼隨想錄算法訓練營DAY58|101.孤島的總面積、102.沉沒孤島、103. 水流問題、104.建造最大島嶼

忙。。。寫了好久。。。。慢慢補吧。 101.孤島的總面積 先把周邊的島嶼變成水dfs def dfs(x, y, graph, s):if x<0 or x>len(graph) or y<0 or y>len(graph[0]) or graph[x][y]0:return sgraph[x][y]0s1s dfs(x1, y, graph, s)s dfs(x-1, y, graph, s)s dfs(…

【爬蟲入門知識講解:xpath】

3.3、xpath xpath在Python的爬蟲學習中&#xff0c;起著舉足輕重的地位&#xff0c;對比正則表達式 re兩者可以完成同樣的工作&#xff0c;實現的功能也差不多&#xff0c;但xpath明顯比re具有優勢&#xff0c;在網頁分析上使re退居二線。 xpath 全稱為XML Path Language 一種…

軟考高級第四版備考--第16天(規劃溝通管理)Plan Communication Management

定義&#xff1a;基于每個干系人或干系人群體的信息需求、可用的組織資產以及具體的項目的需求&#xff0c;為項目溝通活動制定恰當的方法和計劃的過程。 作用&#xff1a; 及時向干系人提供相關信息&#xff1b;引導干系人有效參與項目&#xff1b;編制書面溝通計劃&#xf…

【基于R語言群體遺傳學】-16-中性檢驗Tajima‘s D及連鎖不平衡 linkage disequilibrium (LD)

Tajimas D Test 已經開發了幾種中性檢驗&#xff0c;用于識別模型假設的潛在偏差。在這里&#xff0c;我們將說明一種有影響力的中性檢驗&#xff0c;即Tajimas D&#xff08;Tajima 1989&#xff09;。Tajimas D通過比較數據集中的兩個&#x1d703; 4N&#x1d707;估計值來…

vue項目中常見的一些preset及其關系

Babel的作用 Babel主要用途是用來做js代碼轉換的&#xff0c;將最新的js語法或者api轉換成低版本瀏覽器可兼容執行的代碼。 語法兼容是指一些瀏覽器新特性增加的js寫法&#xff0c;例如箭頭函數 ()>{}&#xff1b;低版本的瀏覽器無法識別這些&#xff0c;會導致一些語法解…

spark shuffle寫操作——UnsafeShuffleWriter

PackedRecordPointer 使用long類型packedRecordPointer存儲數據。 數據結構為&#xff1a;[24 bit partition number][13 bit memory page number][27 bit offset in page] LongArray LongArray不同于java中long數組。LongArray可以使用堆內內存也可以使用堆外內存。 Memor…

秋招突擊——7/9——字節面經

文章目錄 引言正文八股MySQL熟悉嗎&#xff1f;講一下MySQL索引的結構&#xff1f;追問&#xff1a;MySQL為什么要使用B樹&#xff1f;在使用MySQL的時候&#xff0c;如何避免索引失效&#xff1f;講一下MySQL的事物有哪幾種特征&#xff1f;MySQL的原子性可以實現什么效果&…

GESP C++ 三級真題(2023年9月)T2 進制判斷

進制判斷 問題描述 N進制數指的是逢N進一的計數制。例如&#xff0c;人們日常生活中大多使用十進制計數&#xff0c; 而計算機底層則一般使用二進制。除此之外&#xff0c;八進制和十六進制在一些場合也是 常用的計數制(十六進制中&#xff0c;一般使用字母A至F表示十至十五…

【區塊鏈+跨境服務】粵澳健康碼跨境互認系統 | FISCO BCOS應用案例

2020 年突如其來的新冠肺炎疫情&#xff0c;讓社會治理體系面臨前所未見的考驗&#xff0c;如何兼顧疫情防控與復工復產成為社會 各界共同努力的目標。區塊鏈技術作為傳遞信任的新一代信息基礎設施&#xff0c;善于在多方協同的場景中發揮所長&#xff0c;從 而為粵澳兩地的疫情…

uniapp上傳文件并獲取上傳進度

1. 上傳普通文件 uni.chooseMessageFile({count: 1,success: (res) > {console.log(res)console.log("res123456", res.tempFiles[0].path)const uploadTask uni.uploadFile({url: http://localhost:8000/demo,filePath: res.tempFiles[0].path,name: file,form…

CSS關于居中的問題

文章目錄 1. 行內和塊級元素自身相對父控件居中1.1. 塊級元素相對父控件居中1.2. 行內元素相對于父控件居中 2. 實現單行文字垂直居中3. 子絕父相實現子元素的水平垂直居中3.1. 方案一3.1.1. 示例 3.2. 方案二3.2.1. 示例 3.3. 方案三(推薦)3.3.1. 示例 3.4. 方案四(了解一下) …

AI大模型知識點大梳理_ai大模型的精度以下哪項描述的準確

AI大模型是什么 AI大模型是指具有巨大參數量的深度學習模型&#xff0c;通常**包含數十億甚至數萬億個參數。**這些模型可以通過學習大量的數據來提高預測能力&#xff0c;從而在自然語言處理、計算機視覺、自主駕駛等領域取得重要突破。 AI大模型的定義具體可以根據參數規模…