サーチ…
備考
ラムダ式は、匿名関数をインラインで作成するための構文です。より正式には、 C#プログラミングガイド :
ラムダ式は、デリゲートまたは式ツリー型の作成に使用できる無名関数です。ラムダ式を使用すると、引数として渡すことも、関数呼び出しの値として返すこともできるローカル関数を記述することができます。
ラムダ式は、 =>
演算子を使用して作成されます。オペレータの左手側にパラメータを入力します。右側には、これらのパラメータを使用できる式を記述します。この式は関数の戻り値として解決されます。もっとまれに、必要に応じて、 {code block}
全体を右側で使用することができます。戻り値の型がvoidでない場合、ブロックにはreturn文が含まれます。
ラムダ式をパラメータとしてメソッドに渡す
List<int> l2 = l1.FindAll(x => x > 6);
ここで、 x => x > 6
は、6を超える要素のみが返されるようにする述語として機能するラムダ式です。
デリゲート初期化の略語としてのラムダ式
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;
上記のラムダ式の構文は、次のような冗長コードと同等です。
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = delegate(int x){
return x * 2;
};
ラムダは `Func`と` Action`の両方
通常、lambdaは簡単な関数を定義するために使われます (一般的にlinq式の文脈で):
var incremented = myEnumerable.Select(x => x + 1);
ここでのreturn
は暗黙的です。
しかし、lambdaとしてアクションを渡すことも可能です:
myObservable.Do(x => Console.WriteLine(x));
複数のパラメータまたはパラメータなしのラムダ式
=>
演算子の左にある式のまわりのカッコを使用して、複数のパラメータを指定します。
delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;
同様に、カッコの空のセットは、関数がパラメータを受け入れないことを示します。
delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";
ステートメントラムダに複数のステートメントを入れる
式ラムダとは異なり、ステートメントラムダにはセミコロンで区切られた複数のステートメントを含めることができます。
delegate void ModifyInt(int input);
ModifyInt addOneAndTellMe = x =>
{
int result = x + 1;
Console.WriteLine(result);
};
ステートメントは中括弧{}
囲まれています。
ステートメントlambdasは式ツリーの作成に使用できないことに注意してください。
Lambdaは `Func`と` Expression`の両方として発行することができます
次のPerson
クラスを仮定します。
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
次のラムダ:
p => p.Age > 18
両方のメソッドの引数として渡すことができます:
public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)
コンパイラはラムダをデリゲートとExpression
の両方に変換することができるためです。
明らかに、LINQプロバイダは、クエリを解析してストアクエリに変換できるように、 Expression
IQueryable<T>
(主にIQueryable<T>
インターフェイスを通じて公開されています)に大きく依存しています。
イベントハンドラとしてのラムダ式
ラムダ式を使用してイベントを処理することができます。これは以下の場合に便利です。
- ハンドラは短いです。
- ハンドラの登録を解除する必要はありません。
ラムダイベントハンドラが使用される良い状況を以下に示します。
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");
コードの将来のある時点で登録されたイベントハンドラの登録を解除する必要がある場合、イベントハンドラの式を変数に保存し、その変数を介して登録/登録解除を行う必要があります。
EventHandler handler = (sender, args) => Console.WriteLine("Email sent");
smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;
これを行わなく、単にそれを解除するために逐語的にラムダ式再入力されている理由( -=
)C#コンパイラは、必ずしも2つの式が等しく考慮していないということです。
EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"
追加のステートメントがラムダ式に追加された場合、コンパイル時にエラーが発生することなく、必要な前後の中括弧が誤って省略される可能性があることに注意してください。例えば:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;
これはコンパイルされますが、ラムダ式(sender, args) => Console.WriteLine("Email sent");
を追加し(sender, args) => Console.WriteLine("Email sent");
イベントハンドラとして使用し、文emailSendButton.Enabled = true;
を実行しemailSendButton.Enabled = true;
すぐに。これを修正するには、ラムダの内容を中括弧で囲む必要があります。これは、最初から中括弧を使用することで避けることができます。ラムダイベントハンドラに追加の文を追加するときや、ラウンドダッシュをラウンドブラケットで囲むときは注意してください。
smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error