C# Action と Func で使うラムダ式
Action と Func は、ラムダ式を格納するためによく使われる汎用デリゲート型です。戻り値の有無によって使い分けます。
Action:戻り値なし
Action は戻り値を持たない処理を表すデリゲートです。引数の数に応じて Action、Action<T>、Action<T1, T2> などを使います。
// 引数なし
Action sayHello = () => Console.WriteLine("Hello!");
sayHello();
// 引数1つ
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice");
// 引数2つ
Action<string, int> repeat = (text, count) =>
{
for (int i = 0; i < count; i++)
Console.WriteLine(text);
};
repeat("Hi", 3);Func:戻り値あり
Func は戻り値を持つ処理を表すデリゲートです。型パラメータの最後が戻り値の型になります。
// 引数なし、戻り値 int
Func<int> getRandomNumber = () => new Random().Next(100);
Console.WriteLine(getRandomNumber());
// 引数 int、戻り値 int
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // 25
// 引数 int, int、戻り値 int
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 4)); // 7両者の違い
Action
戻り値なし(void 相当)。副作用のある処理に使う。
Func
戻り値あり。最後の型パラメータが戻り値の型。
メソッドの引数として渡す
Action や Func をメソッドの引数にすることで、処理を外部から注入できます。
void ProcessNumbers(List<int> numbers, Func<int, int> transform)
{
foreach (var n in numbers)
{
Console.WriteLine(transform(n));
}
}
var list = new List<int> { 1, 2, 3, 4, 5 };
ProcessNumbers(list, x => x * 2); // 2, 4, 6, 8, 10
ProcessNumbers(list, x => x * x); // 1, 4, 9, 16, 25このパターンは LINQ の内部でも広く使われています。Where や Select に渡すラムダ式は、まさに Func として受け取られているのです。
var numbers = new List<int> { 1, 2, 3, 4, 5 };
// Where は Func<int, bool> を受け取る
var evens = numbers.Where(n => n % 2 == 0);
// Select は Func<int, TResult> を受け取る
var doubled = numbers.Select(n => n * 2);Action と Func を理解すれば、ラムダ式の活用範囲が大きく広がります。