C# Action と Func で使うラムダ式

ActionFunc は、ラムダ式を格納するためによく使われる汎用デリゲート型です。戻り値の有無によって使い分けます。

Action:戻り値なし

Action は戻り値を持たない処理を表すデリゲートです。引数の数に応じて ActionAction<T>Action<T1, T2> などを使います。

// 引数なし
Action sayHello = () =&gt; Console.WriteLine("Hello!");
sayHello();

// 引数1つ
Action&lt;string&gt; greet = name =&gt; Console.WriteLine($"Hello, {name}!");
greet("Alice");

// 引数2つ
Action&lt;string, int&gt; repeat = (text, count) =&gt;
{
    for (int i = 0; i &lt; count; i++)
        Console.WriteLine(text);
};
repeat("Hi", 3);

Func:戻り値あり

Func は戻り値を持つ処理を表すデリゲートです。型パラメータの最後が戻り値の型になります。

// 引数なし、戻り値 int
Func&lt;int&gt; getRandomNumber = () =&gt; new Random().Next(100);
Console.WriteLine(getRandomNumber());

// 引数 int、戻り値 int
Func&lt;int, int&gt; square = x =&gt; x * x;
Console.WriteLine(square(5)); // 25

// 引数 int, int、戻り値 int
Func&lt;int, int, int&gt; add = (a, b) =&gt; a + b;
Console.WriteLine(add(3, 4)); // 7

両者の違い

Action

戻り値なし(void 相当)。副作用のある処理に使う。

Func

戻り値あり。最後の型パラメータが戻り値の型。

メソッドの引数として渡す

ActionFunc をメソッドの引数にすることで、処理を外部から注入できます。

void ProcessNumbers(List&lt;int&gt; numbers, Func&lt;int, int&gt; transform)
{
    foreach (var n in numbers)
    {
        Console.WriteLine(transform(n));
    }
}

var list = new List&lt;int&gt; { 1, 2, 3, 4, 5 };

ProcessNumbers(list, x =&gt; x * 2);      // 2, 4, 6, 8, 10
ProcessNumbers(list, x =&gt; x * x);      // 1, 4, 9, 16, 25

このパターンは LINQ の内部でも広く使われています。WhereSelect に渡すラムダ式は、まさに Func として受け取られているのです。

var numbers = new List&lt;int&gt; { 1, 2, 3, 4, 5 };

// Where は Func&lt;int, bool&gt; を受け取る
var evens = numbers.Where(n =&gt; n % 2 == 0);

// Select は Func&lt;int, TResult&gt; を受け取る
var doubled = numbers.Select(n =&gt; n * 2);

ActionFunc を理解すれば、ラムダ式の活用範囲が大きく広がります。