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

C# 內建委派大全:Action、Func、Predicate 使用指南

     編輯:關於C#

為什麼要用內建委派

.NET 框架內建 Action、Func、Predicate 涵蓋 99% 的委派場景,避免自訂委派型別,提高程式碼可讀性、相容性與標準化程度。

委派類型對照表

委派參數回傳值適用場景
Action無void無參數、無回傳的動作
Action<T>1 個void單參數動作
Action<T1,T2>2 個void雙參數動作
... 最多 Action<T1..T16>16 個void多參數動作
Func<TResult>無TResult無參數、有回傳的函式
Func<T, TResult>1 個TResult單參數函式
... 最多 Func<T1..T16, TResult>16 個TResult多參數函式
Predicate<T>1 個 (T)bool條件判斷、篩選
Comparison<T>2 個 (T, T)int排序比較
Converter<TInput, TOutput>1 個 (TInput)TOutput型別轉換

實用範例

1. Action - 執行動作


// 無參數
Action greet = () => Console.WriteLine("Hello World!");
greet();

// 單參數
Action log = msg => Console.WriteLine($"[LOG] {msg}");
log("應用程式啟動");

// 多參數
Action printTimes = (msg, n) => {
    for (int i = 0; i < n; i++) Console.WriteLine(msg);
};
printTimes("重複列印", 3);

2. Func - 計算與轉換


// 無參數有回傳
Func now = () => DateTime.Now;
Console.WriteLine(now());

// 單參數轉換
Func intToHex = x => x.ToString("X");
Console.WriteLine(intToHex(255)); // FF

// 多參數運算
Func hypot = (a, b) => Math.Sqrt(a*a + b*b);
Console.WriteLine(hypot(3, 4)); // 5

// 實際應用:LINQ 投影
var numbers = new[] { 1, 2, 3, 4, 5 };
var squares = numbers.Select(n => n * n); // Select 接受 Func

3. Predicate - 條件判斷


Predicate isEven = x => x % 2 == 0;
Predicate isNotNullOrEmpty = s => !string.IsNullOrEmpty(s);

// List 篩選
var list = new List { 1, 2, 3, 4, 5, 6 };
var evens = list.FindAll(isEven); // [2, 4, 6]
var firstEven = list.Find(isEven); // 2
var index = list.FindIndex(isEven); // 1

// Array 篩選
var arr = new[] { "apple", "", "banana", null, "cherry" };
var valid = Array.FindAll(arr, isNotNullOrEmpty); // ["apple", "banana", "cherry"]

4. Comparison - 自訂排序


var people = new List
{
    new Person { Name = "Bob", Age = 30 },
    new Person { Name = "Alice", Age = 25 },
    new Person { Name = "Charlie", Age = 35 }
};

// 依年齡遞增
people.Sort((a, b) => a.Age.CompareTo(b.Age));

// 依名稱長度遞減
people.Sort((a, b) => b.Name.Length.CompareTo(a.Name.Length));

進階:委派鏈與多播


Action multiCast = null;
multiCast += s => Console.WriteLine($"Handler1: {s}");
multiCast += s => Console.WriteLine($"Handler2: {s}");
multiCast += s => Console.WriteLine($"Handler3: {s}");

multiCast("事件觸發");
// 輸出:
// Handler1: 事件觸發
// Handler2: 事件觸發
// Handler3: 事件觸發

// 移除特定處理器
multiCast -= s => Console.WriteLine($"Handler2: {s}"); // 注意:需保留相同委派實例才能移除

最佳實踐

  1. 優先使用內建委派,除非有極特殊語義需求(如領域專用名稱)
  2. Lambda 表達式是建立委派實例的標準寫法,簡潔且支援閉包
  3. 避免過度使用多播委派(+=),事件模式請用 event 關鍵字
  4. 區分 Func 與 Expression<Func>:後者為表達式樹,用於 IQueryable/LINQ to SQL/Entity Framework
  5. 方法群組轉換:list.FindAll(IsEven) 等同 list.FindAll(x => IsEven(x)),更簡潔

// 靜態方法群組轉換範例
static bool IsEven(int x) => x % 2 == 0;
var evens = list.FindAll(IsEven); // 自動轉為 Predicate

掌握內建委派,讓 C# 程式碼更符合慣例、更易維護、更好整合 LINQ 與標準庫。

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