ラムダ式 (インライン コード) などの新機能の出現により、デリゲートや匿名メソッドを使用する必要がなくなったということですか? 私が見たほとんどすべてのサンプルでは、新しい構文を使用して書き直すためのものです。
まだデリゲートとラムダ式を使用する必要がある場所は機能しませんか?
ラムダ式 (インライン コード) などの新機能の出現により、デリゲートや匿名メソッドを使用する必要がなくなったということですか? 私が見たほとんどすべてのサンプルでは、新しい構文を使用して書き直すためのものです。
まだデリゲートとラムダ式を使用する必要がある場所は機能しませんか?
はい、匿名デリゲートとラムダ式を直接使用しても機能しない場所があります。
メソッドが型指定されていないデリゲートを取る場合、コンパイラは匿名のデリゲート/ラムダ式を何に解決するかを認識せず、コンパイラ エラーが発生します。
public static void Invoke(Delegate d)
{
d.DynamicInvoke();
}
static void Main(string[] args)
{
// fails
Invoke(() => Console.WriteLine("Test"));
// works
Invoke(new Action(() => Console.WriteLine("Test")));
Console.ReadKey();
}
失敗したコード行では、「デリゲート型ではないため、ラムダ式を型 'System.Delegate' に変換できません」というコンパイラ エラーが発生します。
lambda is shortcut for anonymous delegate, but you will always be using delegates. the delegate specifies the methods signature. you can just do this:
delegate(int i) { Console.WriteLine(i.ToString()) }
can be replaced with
f => Console.WriteLine(f.ToString())
ラムダ式は、デリゲートを置き換える (隠す) 特効薬ではありません (また、そうなるように意図されていませんでした)。次のような小さなローカルなものに最適です。
List<string> names = GetNames();
names.ForEach(Console.WriteLine);
一方で、それらを誤用するのは非常に簡単です。長いまたは複雑なラムダ式は、次のようになる傾向があります。
では、「デリゲートや匿名メソッドを使用する必要がなくなったということですか?」いいえ – 時間/可読性を勝ち取る場合は Lambda 式を使用します。それ以外の場合は、デリゲートの使用を検討してください。
C# では、デリゲートには 2 つの意味があります。
キーワードdelegate
を使用して、関数シグネチャ タイプを定義できます。これは通常、高階関数、つまり他の関数を引数として取る関数のシグネチャを定義するときに使用されます。このデリゲートの使用は、依然として適切です。
このdelegate
キーワードは、インライン無名関数の定義にも使用できます。関数が単一の式である場合、ラムダ構文はより単純な代替手段です。
ラムダはデリゲートの単なる構文糖衣であり、単なるインラインではありません。次のことができます。
s.Find(a =>
{
if (a.StartsWith("H"))
return a.Equals("HI");
else
return !a.Equals("FOO");
});
また、イベントを定義するとき、または多くの引数があり、呼び出されるメソッドを実際に強く型付けしたい場合は、引き続きデリゲートが使用されます。
Lambda expressions are just "syntactic sugar", the compiler will generate appropriate delegates for you. You can investigate this by using Lutz Roeder's Reflector.
古い構文のそれほど大きな利点ではないのdelegate
は、メソッド本体で使用しない場合はパラメーターを指定する必要がないことです。msdnから
ラムダ式にはない機能を匿名メソッドが提供するケースが 1 つあります。匿名メソッドを使用すると、パラメーター リストを省略できます。これは、匿名メソッドをさまざまなシグネチャを持つデリゲートに変換できることを意味します。これは、ラムダ式では不可能です。
たとえば、次のことができます。
Action<int> a = delegate { }; //takes 1 argument, but not specified on the RHS
これは失敗しますが:
Action<int> a = => { }; //omitted parameter, doesnt compile.
このテクニックは、主に次のようなイベント ハンドラーを作成するときに役立ちます。
button.onClicked += delegate { Console.WriteLine("clicked"); };
これは強力な利点ではありません。常に新しい構文を採用することをお勧めします。