C#のLINQで何気なく使っているラムダ式について。


まずはLINQのサンプルをどうぞ

こちらをご覧ください。C#のソースコードで、LINQのSelectメソッドのサンプルです。

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] a = { 1, 2, 3, 4, 5 };
        var result = a.Select(c => c + 3);

        foreach (var item in result) Console.WriteLine(item);

        Console.Read();
    }
}

実行結果はこちら。配列のアイテムすべてに 3 が足されています。

さてさて、c => c + 3はラムダ式による書き方ですね。

このc => c + 3はいったい何者なのか?
少しずつ書き換えながら考えていきます。

ラムダ式を書き換えていくよ

        var result = a.Select(c => c + 3);

このc => c + 3って、cを渡すとc + 3という結果を返す、まるでひとつの関数みたいな働きをしてますね。
cが引数で、c + 3が返り値、みたいな。

実はこれ、下記のように書き換えてもまったく同じ結果となります。

        var result = a.Select((int c) => c + 3 );

さっきの書き方だとcがいきなり出てきてビックリでしたが、(int c)と書けばちゃんと引数の宣言に見える!
intが省略されていたのです。
だってc + 3;とかやってるし、どう見てもint型でしょ。型推論というやつです。型推論可能なときは型指定を省略できるんですねえ。

さらにここから、下記のように書き換えも可能です。

        var result = a.Select((int c) => { return c + 3; });

さっきまではc + 3がポツンと書いてあったけど、{ return c + 3; }と書けばちゃんと値を返しているように見える!
returnも省略可能なんですねえ。

ちなみに{}の中、何行も書くことができるよ。

        var result = a.Select((int c) => { int tmp = c + 3; return tmp; });

まぁ何行も書くんだったらちゃんと改行すべきだと思うけど…。

        var result = a.Select(
            (int c) =>
            {
                int tmp = c + 3;
                return tmp;
            }
        );

ここまで書き換えると、なんかもう完全に関数っぽい見た目ですね。

ラムダ式は「匿名関数」の書き方のひとつ!

ラムダ式で省略されていたところを丁寧に書いていくと、関数っぽい見た目になりました。
それもそのはず、匿名関数を書くための手段のひとつがラムダ式なんです!

さっきSelectメソッドに渡していた、

            (int c) =>
            {
                int tmp = c + 3;
                return tmp;
            }

を、あえてラムダ式を使わずに書くと、

            delegate(int c)
            {
                int tmp = c + 3;
                return tmp;
            }

はい、どう見ても関数です。

よく見るとdelegateというキーワードが出現していますね。
匿名関数は通常、デリゲート(delegate)という特別な変数に入れて扱うものなのです。
デリゲートはいわば「関数の定義への参照」みたいなものだと筆者は思っておりますが、詳細が気になる方は各自ググってください!(丸投げ)

まとめ

        var result = a.Select(c => c + 3);

C#のLINQをしっかり理解したい場合、
デリゲートを勉強して、匿名関数を勉強して、ラムダ式を勉強して、LINQを勉強する、
という手順を踏むのが正攻法ですかね。

でも筆者のように「いきなり仕事でLINQのプログラムをやることになったゾ…」という人は、
この手順を知らないまま、検索ワード「LINQ 入門」とかでググってしまい、
ラムダ式って何?匿名関数って何?デリゲートって何?となってしまいがちな気がする…だって自分がそうだったから…。

勉強は積み重ねが大切ってよく言うけど、何を積み重ねればいいのかを明確にするのも大切ですな。

参考文献