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

C# 2.0 泛型與匿名方法:自訂集合實作 FindAll 等內建演算法

     編輯:關於C語言

背景

.NET 2.0 引入泛型、匿名方法與 Predicate<T> 委派,使 List<T>.FindAll 等內建演算法極具表達力。本文示範如何在**自訂集合類別**中實作相同模式。

系統內建委派定義

public delegate bool Predicate<T>(T obj);

List<T>.FindAll 內部邏輯相當於:

public List<T> FindAll(Predicate<T> match)
{
    List<T> result = new List<T>();
    foreach (T item in this)
        if (match(item)) result.Add(item);
    return result;
}

自訂泛型向量類別 MyVec<T>

using System;
using System.Collections.Generic;
using System.Text;

public class MyVec<T> : IEnumerable<T>
{
    private List<T> _inner = new List<T>();

    // 運算子多載:支援 vec += item 語法
    public static MyVec<T> operator +(MyVec<T> vec, T item)
    {
        vec._inner.Add(item);
        return vec;
    }

    // 實作 FindAll
    public MyVec<T> FindAll(Predicate<T> match)
    {
        MyVec<T> result = new MyVec<T>();
        foreach (T item in _inner)
            if (match(item)) result += item;
        return result;
    }

    // 實作 IEnumerable<T> 支援 foreach
    public IEnumerator<T> GetEnumerator() => _inner.GetEnumerator();
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        foreach (T item in _inner) sb.Append(item).Append(',');
        if (sb.Length > 0) sb.Length--; // 移除尾端逗號
        return sb.ToString();
    }
}

使用範例

static void Main()
{
    MyVec<int> vec = new MyVec<int>();
    vec += 12;
    vec += 15;
    vec += 32;

    // 匿名方法作為 Predicate
    MyVec<int> found = vec.FindAll(delegate(int x) { return x < 20; });
    // C# 3.0+ Lambda 更簡潔:vec.FindAll(x => x < 20);

    Console.WriteLine("原始:" + vec);      // 12,15,32
    Console.WriteLine("找到:" + found);   // 12,15
    Console.ReadLine();
}

擴充更多內建演算法


// 存在性檢查
public bool Exists(Predicate<T> match) => _inner.Exists(match);

// 單一元素查詢
public T Find(Predicate<T> match) => _inner.Find(match);
public int FindIndex(Predicate<T> match) => _inner.FindIndex(match);

// 轉換
public MyVec<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
{
    MyVec<TOutput> result = new MyVec<TOutput>();
    foreach (T item in _inner) result += converter(item);
    return result;
}

// 排序 (需 T 實作 IComparable<T>)
public void Sort() => _inner.Sort();
public void Sort(Comparison<T> comparison) => _inner.Sort(comparison);

// 迴圈動作
public void ForEach(Action<T> action) => _inner.ForEach(action);

關鍵設計點

  1. 委派參數化演算法:將判斷邏輯 (Predicate<T>)、轉換邏輯 (Converter<T, TOutput>)、動作 (Action<T>) 參數化,集合本身只負責遍歷與控制流程。
  2. 實作 IEnumerable<T>:讓自訂集合支援 foreach、LINQ 擴充方法 (.Where(), .Select() 等)。
  3. 封裝內部儲存:範例以 List<T> 為底層,實務上可換成陣列、鏈結串列、樹狀結構等,對外介面不變。
  4. 運算子多載:提供 += 語法糖,提升流暢度 (Fluent API)。

結語

掌握 Predicate<T>/Action<T>/Func<T, TResult> 委派模式,即可為任意資料結構賦予 LINQ 風格的查詢能力,這正是 C# 函數式特性威力的核心體現。

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