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

C# 2.0 新特性總覽:泛型、匿名方法、迭代器與部分型別

     編輯:關於C語言

C# 2.0 四大核心擴充

  1. 泛型:型別參數化,編譯期型別安全,消除裝箱/轉型
  2. 匿名方法:內聯程式碼區塊轉委派,支援閉包捕獲外部變數
  3. 迭代器:yield return 簡化列舉器實作,狀態機自動產生
  4. 部分型別:類別/結構/介面定義拆分多檔案,利於工具生成碼隔離

相容性設計原則

  • 零新增關鍵字:where、yield、partial 僅在特定語境有特殊意義,其他場合仍可作識別項
  • 現有程式碼零修改重新編譯即可運行

泛型深度解析

為何需要泛型?

Object 型別缺點:

  • 值型別須裝箱/拆箱 → 效能損耗、GC 壓力
  • 執行期型別檢查 → InvalidCastException 風險
  • 無法強制元素型別 → 編譯期無法攔截錯誤
// 非泛型 Stack
Stack s = new Stack();
s.Push(new Customer());
string x = (string)s.Pop();  // 編譯通過,執行炸裂

// 泛型 Stack<T>
Stack<Customer> s = new Stack<Customer>();
s.Push(new Customer());
Customer c = s.Pop();  // 型別安全,無轉型
s.Push(3);  // 編譯錯誤

建構與使用泛型

public class Stack<T> {
    T[] items; int count;
    public void Push(T item) { ... }
    public T Pop() { ... }
}

// 使用:構造型別 Stack<int>
Stack<int> s = new Stack<int>();
s.Push(3);
int x = s.Pop();  // 直接得 int,無拆箱
  • T 為型別參數佔位符,使用時指定實際型別引數
  • 構造型別 Stack<int> 內部儲存 int[] 而非 object[]
  • 多型別參數:Dictionary<K, V>

泛型型別具現化

  • JIT 於首次使用構造型別時,將 IL + 中繼資料 + 型別引數 → 原生碼
  • 值型別:每個構造型別獨立原生碼拷貝(int、double 不同碼)
  • 參考型別:共享單一原生碼(指標大小相同)

型別參數約束

public class Dictionary<K, V> where K : IComparable<K> {
    public void Add(K key, V value) {
        if (key.CompareTo(other) < 0) ...  // 直接呼叫,無轉型
    }
}

// 多重約束
public class EntityTable<K, E> 
    where K : IComparable<K>, IPersistable
    where E : Entity, new() { ... }

約束類型:介面、基類、new()(公用無參建構子)、class/struct(參考/值型別)、unmanaged、notnull、default。

泛型方法

void PushMultiple<T>(Stack<T> stack, params T[] values) {
    foreach (T v in values) stack.Push(v);
}

// 呼叫:型別推斷自動判斷 T
Stack<int> s = new Stack<int>();
PushMultiple(s, 1, 2, 3, 4);  // 推斷 T=int

匿名方法

// 傳統:獨立方法 + 委派建立
btn.Click += new EventHandler(Btn_Click);
void Btn_Click(object s, EventArgs e) { list.Add(txt.Text); }

// 匿名方法:內聯
btn.Click += delegate { list.Add(txt.Text); };

// 需存取參數時
btn.Click += delegate(object s, EventArgs e) { 
    MessageBox.Show(((Button)s).Text); 
};

捕獲外部變數(閉包):匿名方法引用區域變數/參數 → 變數生命週期延長至委派可被 GC 為止。編譯器自動提升為封裝類別欄位。

方法群組轉換

// 簡化委派建立
btn.Click += Btn_Click;           // 代替 new EventHandler(Btn_Click)
Apply(arr, Math.Sin);             // 代替 new Function(Math.Sin)

迭代器

public class Stack<T> : IEnumerable<T> {
    public IEnumerator<T> GetEnumerator() {
        for (int i = count - 1; i >= 0; --i)
            yield return items[i];  // 產生下一個值
    }
}

// 使用
foreach (int i in stack) Console.Write(i);  // 隱式呼叫 GetEnumerator
  • yield return:產生值並掛起
  • yield break:結束迭代
  • 編譯器自動產生狀態機類別實作 IEnumerator
  • 可用於屬性/方法回傳 IEnumerable<T> 實現多種列舉方式

部分型別

// File1.cs (工具生成)
public partial class Customer {
    private int id; private string name;
    public Customer() { ... }
}

// File2.cs (手寫邏輯)
public partial class Customer {
    public void SubmitOrder(Order o) { orders.Add(o); }
    public bool HasOrders() { return orders.Count > 0; }
}

// 編譯合併為單一類別
  • 所有部分需同組件編譯,不可跨組件擴充
  • 適用:設計工具生成碼隔離、大型類別協作開發
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved