C# 7.0の新しい実装を調べていますが、ローカル関数が実装されていることは興味深いのですが、ラムダ式よりもローカル関数が優先されるシナリオは想像できません。また、この 2 つの違いは何でしょうか。
anonymous
ラムダ式は関数であり、ローカル関数は関数ではないことは理解していますが、ローカル関数がラムダ式よりも優れているという現実世界のシナリオを理解できません。
どんな例でも大歓迎です。ありがとうございます。
ベストアンサー1
これは、ローカル関数が初めて議論された C# Design Meeting Notes で Mads Torgersen によって説明されました。
ヘルパー関数が必要です。これは単一の関数内からのみ使用し、その関数のスコープ内にある変数と型パラメータを使用する可能性が高いです。一方、ラムダとは異なり、ファーストクラス オブジェクトとして必要ないため、デリゲート型を指定して実際のデリゲート オブジェクトを割り当てる必要はありません。また、再帰的または汎用的にしたり、反復子として実装したりする必要がある場合もあります。
さらに詳しく説明すると、利点は次のとおりです。
パフォーマンス。
ラムダを作成するときはデリゲートを作成する必要がありますが、この場合は不要な割り当てになります。ローカル関数は実際には単なる関数であり、デリゲートは必要ありません。
また、ローカル関数はローカル変数のキャプチャに効率的です。ラムダは通常、変数をクラスにキャプチャしますが、ローカル関数は構造体 ( を使用して渡される
ref
) を使用できるため、割り当てを回避できます。これは、ローカル関数の呼び出しコストが安くなり、インライン化できるため、パフォーマンスがさらに向上する可能性があることも意味します。
ローカル関数は再帰的に実行できます。
ラムダも再帰的にできますが、最初に
null
デリゲート変数に割り当ててからラムダを割り当てるという厄介なコードが必要になります。ローカル関数は自然に再帰的になります (相互再帰を含む)。ローカル関数はジェネリックにすることができます。
ラムダは、具体的な型の変数に割り当てる必要があるため、ジェネリックにすることはできません (その型は外部スコープからのジェネリック変数を使用できますが、それは同じではありません)。
ローカル関数はイテレータとして実装できます。
ラムダ式では、
yield return
(andyield break
) キーワードを使用してIEnumerable<T>
-returning 関数を実装することはできません。ローカル関数では可能です。ローカル関数の方が見栄えが良いです。
これは上記の引用では言及されておらず、私の個人的な偏見かもしれませんが、ラムダをデリゲート変数に割り当てるよりも、通常の関数構文の方が見栄えが良いと思います。ローカル関数もより簡潔です。
比較する:
int add(int x, int y) => x + y; Func<int, int, int> add = (x, y) => x + y;