C# 静的ラムダ(static lambda)

C# 9.0 で導入された静的ラムダ(static lambda)は、外部変数のキャプチャを禁止するラムダ式です。意図しないキャプチャを防ぎ、パフォーマンスの向上にも寄与します。

基本的な書き方

ラムダ式の前に static キーワードを付けることで、静的ラムダになります。

// 通常のラムダ式
Func<int, int> normalLambda = x => x * 2;

// 静的ラムダ
Func<int, int> staticLambda = static x => x * 2;

どちらも同じ結果を返しますが、静的ラムダは外部変数をキャプチャできない制約があります。

キャプチャを禁止する効果

静的ラムダで外部変数を参照しようとすると、コンパイルエラーになります。

int multiplier = 3;

// コンパイルエラー:静的ラムダは外部変数をキャプチャできない
// Func<int, int> lambda = static x => x * multiplier;

これにより、意図せずクロージャを作ってしまうミスを防げます。

なぜ静的ラムダが有用か

通常のラムダ式が外部変数をキャプチャすると、コンパイラは内部的にクラスを生成してキャプチャされた変数を保持します。これにはオーバーヘッドが伴います。

通常のラムダ式

キャプチャ時にヒープ割り当てが発生する可能性がある

静的ラムダ

キャプチャ不可のため、余計なアロケーションが発生しない

ホットパス(頻繁に実行される処理)では、この差がパフォーマンスに影響することがあります。

静的ローカル関数との組み合わせ

同様の機能は静的ローカル関数でも実現できます。

int Process(int value)
{
    // 静的ローカル関数:外部変数をキャプチャできない
    static int Double(int x) => x * 2;
    
    return Double(value);
}

使いどころ

静的ラムダは以下のような場面で有効です。

パフォーマンスが重要な処理

LINQ のコールバックなど、何度も呼ばれる処理でアロケーションを減らしたい場合。

意図の明示

「このラムダは外部に依存しない」ことをコードで明示したい場合。

バグの予防

意図しないキャプチャによるバグを防ぎたい場合。

var numbers = new List<int> { 1, 2, 3, 4, 5 };

// 静的ラムダで意図を明示
var doubled = numbers.Select(static x => x * 2);

静的ラムダは必須の機能ではありませんが、コードの意図を明確にし、潜在的な問題を防ぐ手段として覚えておくと便利です。