はじめに
4月で C# の基本的な文法を学んだ。しかし、ここから先に進もうとすると、
ラムダ式を避けては通れないと分かった。
誤りについては優しく指摘してくださると嬉しいです。
ラムダ式
一言で言ってしまえば、その場限りの関数をサクッと定義する糖衣構文。
引数 => 処理内容の形で記述する。x => x * 2のような感じ。
使用例
デリゲート
多くの場合はデリゲートと一緒に使う。
ラムダ式を使わない場合、デリゲートのインスタンスを使う場所から離れた場所に定義が散らばってしまう。しかもデリゲートのためだけにメソッドを書かねばならず、面倒くさいし読みづらい。
internal class Program
{
static void Main(string[] args)
{
// 通常のメソッドを定義
int Double(int x)
{
return x * 2;
}
// デリゲートに代入
Func<int, int> transformer = Double;
Console.WriteLine(transformer(5)); // 10
}
}
これをラムダ式を使って書くとこうなる。
処理の中身を使う場所にそのまま書ける。
internal class Program
{
static void Main(string[] args)
{
// transformerデリゲートに引数xを2乗するメソッドを登録
Func<int, int> transformer = x => x * 2;
Console.WriteLine(transformer(5)); // 10
}
}
Doubleメソッドの定義が不要になり、
デリゲートへの代入と処理の中身が一行にまとまって読みやすくなった。
デリゲートなので2つ以上の関数を扱う場合にも恩恵が大きい。
// リストの各要素に「何か」を適用してリストを返す
static List<int> Apply(List<int> numbers, Func<int, int> transform)
{
var result = new List<int>();
foreach (var n in numbers)
result.Add(transform(n));
return result;
}
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var doubled = Apply(numbers, x => x * 2); // { 2, 4, 6, 8, 10 }
var squared = Apply(numbers, x => x * x); // { 1, 4, 9, 16, 25 }
// ラムダ式を使わない場合、2倍・2乗のメソッドを書く必要はない。
LINQ
LINQを書く時にも使う機会が多い。
使用頻度の多い.Select()も、引数はデリゲートになっており、その中にラムダ式で書いた関数を登録することで処理を行っている。(そのため、デリゲートとLINQで節を分けるのはどうかとも思ったが)
例えば、以下は1~6までの整数が入ったリストについて、偶数を2乗したリストを返す。
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evens = numbers.Where(x => x % 2 == 0).Select(x => x * x).ToList();
// evens: { 4, 16, 36 }
さいごに
ラムダ式は簡潔で便利だが、乱用しすぎると却って何をしているのか分かりにくくなりそう。また、ラムダ式本体よりもデリゲートをしっかり理解しておく方が先決だと思う(複雑なロジックはラムダ式では書けなさそうなので)。
参考