首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 2.0 泛型程式設計入門:動機、原理、約束與進階主題

     編輯:關於C#

為什麼需要泛型?

object 型別集合三大缺點:

  1. 效能損失:實值型別頻繁裝箱/拆箱,GC 壓力大。
  2. 型別不安全:stack.Push(new Node1()); Node2 n = (Node2)stack.Pop(); 編譯通過,執行期拋 InvalidCastException。
  3. 程式碼重複:每種型別寫一份強型別包裝類。

泛型如何解決?


// 泛型堆疊
public class Stack
{
    private T[] items;
    public T Pop() => items[--top];
    public void Push(T item) => items[top++] = item;
}

// 使用
var intStack = new Stack();
intStack.Push(10);
// intStack.Push("abc"); // 編譯錯誤,型別安全

var strStack = new Stack();
strStack.Push("hello");

編譯與執行原理

  1. 原始碼編譯為 IL,T 為佔位符。
  2. JIT 在第一次使用特定封閉型別時(如 Stack),產生專屬機器碼(Stack 專用版本)。
  3. 實值型別各自產生獨立程式碼;參考型別共享一份程式碼(因皆為指標大小)。
  4. 不同封閉型別 = 不同型別:Stack 與 Stack 無繼承關係,靜態成員互不共享。

型別約束詳解


public class Repository 
    where T : class, IEntity, new()  // 參考型別、實作介面、有無參建構子
    where TKey : IEquatable          // 實值/參考型別皆可,需實作介面
{
    public T Create() => new T();          // 需 new() 約束
    public bool Exists(TKey id) => ...;    // 需 IEquatable 比較
}

靜態建構子觸發時機

每個封閉型別獨立觸發:

  • 該封閉型別第一次被實例化。
  • 該封閉型別任何靜態成員首次被存取。

方法多載解析規則


public class Demo
{
    public void M(T a, int b) { }      // 泛型方法 1
    public void M(int a, T b) { }      // 泛型方法 2
    public void M(int a, int b) { }    // 一般方法
}

// Demo m = new Demo();
// m.M(1, 2); // 呼叫一般方法 (優先)
// m.M(1, "x"); // 呼叫 M(int, T) -> T=string

原則:**一般方法優先 > 具體型別匹配 > 泛型推斷**。

泛型應用範疇

  • 類別、結構、介面、委派、方法
  • 委派範例:public delegate TResult Func(T arg);(協變/逆變)

結語

泛型以優雅語法實現「演算法與資料結構與型別分離」,大幅提升效能、安全性與複用性。C# 未來版本將持續擴展(如預設介面方法、泛型數學介面)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved