首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 委託集合:List<Func<int>> 深度解析與實戰應用

     編輯:程式設計綜合問答

核心概念釐清

Func<int> 是 .NET 內建的泛型委託類型,代表「無參數、返回 int 的方法簽名」。它不是方法本身,而是**方法的類型安全封裝**,可將符合簽名的方法、Lambda 表達式、匿名方法作為對象存儲、傳遞、調用。

// 內建定義(簡化版)
public delegate TResult Func();

為什麼需要委託集合?

  • 策略模式實現:運行時動態選擇演算法
  • 插件/擴展機制:第三方代碼註冊處理邏輯
  • 事件多播替代:精確控制調用順序、攔截返回值
  • 延遲執行序列:構建任務管道、中介軟體鏈

完整實戰範例

using System;
using System.Collections.Generic;
using System.Linq;

public class DelegateCollectionDemo
{
    // 模擬:不同來源生成「當前時間戳」的策略
    private static readonly List> _timestampGenerators = new()
    {
        // 策略 1:標準年月日時分
        () => int.Parse(DateTime.Now.ToString("yyMMddHHmm")),
        
        // 策略 2:Unix 時間戳(秒)
        () => (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
        
        // 策略 3:毫秒級時間戳(取後 8 位)
        () => (int)(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond % 100_000_000),
        
        // 策略 4:自定義業務邏輯(如:工作日序號)
        () => GetBusinessDaySequence()
    };

    public static void Main()
    {
        Console.WriteLine("=== 委託集合演示 ===\n");
        
        // 1. 依序執行所有策略
        Console.WriteLine("1. 遍歷執行所有生成器:");
        for (int i = 0; i < _timestampGenerators.Count; i++)
        {
            var generator = _timestampGenerators[i];
            int result = generator();  // 調用委託
            Console.WriteLine($"   策略 {i+1}: {result}");
        }

        // 2. LINQ 查詢:篩選結果大於某值的策略
        Console.WriteLine("\n2. LINQ 篩選 (結果 > 20000000):");
        var filtered = _timestampGenerators
            .Select((f, idx) => new { Index = idx, Value = f() })
            .Where(x => x.Value > 20_000_000);
        foreach (var item in filtered)
            Console.WriteLine($"   策略 {item.Index+1}: {item.Value}");

        // 3. 動態添加/移除策略(運行時擴展)
        Console.WriteLine("\n3. 動態註冊新策略:");
        _timestampGenerators.Add(() => Environment.TickCount & 0x7FFFFFFF);
        Console.WriteLine($"   新策略結果: {_timestampGenerators.Last()()}");

        // 4. 組合模式:建立複合策略
        Console.WriteLine("\n4. 組合策略(取多個策略的最大值):");
        Func composite = () => _timestampGenerators.Max(f => f());
        Console.WriteLine($"   最大值: {composite()}");
    }

    private static int GetBusinessDaySequence()
    {
        // 簡化:年初至今的工作日數
        var start = new DateTime(DateTime.Now.Year, 1, 1);
        int days = (DateTime.Now - start).Days;
        return days * 100 + DateTime.Now.Hour; // 偽業務邏輯
    }
}

進階用法:帶參數的委託集合

// 處理字串的轉換管道
var stringProcessors = new List>
{
    s => s.Trim(),
    s => s.ToLowerInvariant(),
    s => s.Replace(" ", "-"),
    s => $"prefix-{s}-suffix"
};

// 鏈式調用
string input = "  Hello World  ";
string result = stringProcessors.Aggregate(input, (current, processor) => processor(current));
Console.WriteLine(result); // 輸出: prefix-hello-world-suffix

效能與記憶體考量

場景建議
高頻調用(每秒萬次)避免 Lambda 捕獲變量導致閉包分配;優先用靜態方法或結構體委託
大量委託存儲考慮 List<delegate> 基類型或陣列 Func<int>[] 減少泛型實例化開銷
多執行緒環境集合操作需加鎖或使用 ConcurrentBag;委託調用本身是線程安全的

常見誤區

  1. 誤以為 Func 是方法:它是委託類型,類似介面,定義「契約」而非「實作」
  2. 捕獲循環變量陷阱:
    // 錯誤:所有委託共享同一個 i
    for (int i = 0; i < 3; i++) 
        actions.Add(() => i); // 全部輸出 3
    
    // 正確:捕獲局部副本
    for (int i = 0; i < 3; i++) {
        int captured = i;
        actions.Add(() => captured); // 輸出 0,1,2
    }

總結

List<Func<int>> 是 C# 函數式編程能力的體現,將「行為」作為一等公民管理。掌握委託集合,能靈活實現策略模式、管道處理、插件架構等進階設計模式,是從「寫代碼」邁向「設計系統」的關鍵技能。

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