この章のテーマ §
ラムダ式と匿名メソッド、=>演算子とdelegate演算子を学びます。これらは名前のないメソッドを定義可能にします。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, int型, string型, 型パラメータ
解説 §
C#では名前のないメソッドを使用できます。通常はラムダ式です。古いソースでは、匿名メソッドという機能が使用されているケースがありますが、新規で使うことはまずありません。
ここでは現役のラムダ式を中心に説明します。
ラムダ式は名前のないメソッドの一種です。通常は変数や引数に入れてそれを経由して使います。
これらは書き換えが可能ですから、動作する内容を都合に応じていつでも書き換えられるのがラムダ式の強みです。
ラムダ式は=>演算子(ラムダ演算子)を使用して記述します。これは不等号ではないことに注意してください。不等号を書きたい時は>=と書きます。
ラムダ式は基本的に【(引数リスト)=>実行する文】という書式で書きますが、書き方のバリエーションは多くあります。たとえば引数が1つの場合、引数リストを加工カッコは省略できます。(サンプルソースのラムダ式2のケースを参照)
さて、ラムダ式を格納する変数を宣言する際には、型が必要です。ラムダ式にも型があります。
通常は、Action型とFunc型を使います。戻り値がないときはAction型を、ある場合はFunc型を使います。これらは、引数の型を型パラメータで示します。たとえば、string型とint型の値を引数で受け取るラムダ式の場合、対応する型がAction<string,int>となります。Func型の場合、最後の型パラメータが戻り値の型を示します。string型を受け取ってint型を返す場合、Func<string,int>となります。
罠の数々 §
- 匿名メソッドを新規に使う可能性はほぼない。しかし、匿名メソッドは、現役の古いソースコードを見ている時に希に出てくるので存在は知っておくと良いだろう。サンプルソースのdelegateキーワードを使った部分がそれである
- 匿名メソッドは最新のC#でもきちんとサポートされていて動作する。これはソースコードの互換を取るためである。新規に使う人はまずいない
- ラムダ式はそれだけでは有り難みが分からないかもしれないが、引数にラムダ式を渡して動作をカスタマイズできる便利なメソッドは多く存在する
- 戻り値のあるラムダ式にはreturn文が必要だが、波括弧抜きで書いた場合は本体そのものが戻り値を示す式として扱われるので、returnキーワードは必要ない。少しややこしいルールだが飲み込んでおこう
- Action型とFunc型の変数、引数には名前のあるメソッドを代入することもできる
参考リンク §
=> 演算子 (C# リファレンス)
ラムダ式 (C# リファレンス)
delegate 演算子 (C# リファレンス)
サンプルソース: lambdaOperator §
Action<string, int> a = (x,y) =>
{
Console.WriteLine($"ラムダ式1");
Console.WriteLine($"x={x}");
Console.WriteLine($"y={y}");
};
Action<string> b = x =>
{
Console.WriteLine($"ラムダ式2");
Console.WriteLine($"x={x}");
};
Action c = () => Console.WriteLine($"ラムダ式3");
Func<int, int, int> d = (x, y) =>
{
Console.WriteLine($"ラムダ式4");
Console.WriteLine($"x={x}");
Console.WriteLine($"y={y}");
return x + y;
};
Action<string, int> e = delegate(string x, int y)
{
Console.WriteLine($"匿名メソッド");
Console.WriteLine($"x={x}");
Console.WriteLine($"y={y}");
};
a("Hello1", 1234);
b("Hello2");
c();
Console.WriteLine($"d(12, 34)={d(12, 34)}");
e("Hello3", 1234);
実行結果 §
ラムダ式1
x=Hello1
y=1234
ラムダ式2
x=Hello2
ラムダ式3
ラムダ式4
x=12
y=34
d(12, 34)=46
匿名メソッド
x=Hello3
y=1234
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
以下のプログラムの実行結果を予測してみよう。
- 実行するものが何もないので、何も実行せずに終わる
- 実行するとnull値を参照したという例外
- 実行すべきものがないのでコンパイラがエラーを出す
[[解答]]