はかせのラボ

私の頭の中を書いていく雑記ブログです

C# ラムダ式

あいさつ

どうも、はかせです。
今回はC#ラムダ式についてです。

ラムダ式とは

よくLINQとかRxとかの記事で見かけるこんなやつ

//listは事前に作ったList<int>
list.Where(value => value % 2 == 0);

この=>使うやつがラムダ式と呼ばれるやつです。

今回は
こいつがなんなのか?
どうしてこいつ使うのか?

といったあたりをやっていきます。

こいつはなんなのか?

処理を値と同じように扱えるようにするやつです。
普通メソッドの引数には値が渡されます。
そのため

//変数宣言して使っても
int ten = 10;
hoge(ten);
//直接リテラル書いても
hoge(10);

どちらもコンパイル通りますし、
どちらも結果は同じです。

(ちなみにリテラルを書くってのは
10とかhogeとかのデータそのものを
ソースコード内に書くことです)

値を渡すだけならこれでいいのですが、
処理を渡したくなったらどうでしょう?

途端にどうすればいいかわからなくなりますよね。
そこで登場したのがデリゲートと言われるものです。
こいつはC++でいう関数ポインタみたいな動きをしてくれます。
C#にはデリゲートの型として
・Func
・Action

の二つが用意されています。

Funcは戻り値あり、
Actionは戻り値なしです。
FuncとActionの件は本題から外れるので割愛しますが、
こいつはメソッドを持つ変数です。
こいつの値にはメソッドを渡してもいいですし、
直接処理のリテラルを書いてもいいです

その処理リテラルを書く方法がラムダ式になるわけですね。
まずラムダ式の記法です。

(引数の型 引数) => {return なんか処理;};

最初の例と微妙に違うじゃないか?
最初の例はこいつの省略形になります。

まずは省略無し

//listは事前に作ったList<int>
list.Where((int value) => { return value % 2 == 0; });

では省略していきましょう。
省略ルールその一
型は推論可能な場合省略できる

//listは事前に作ったList<int>
list.Where((value) => { return value % 2 == 0; });

省略ルールその二
引数が一つの場合に限り()を省略できる

//listは事前に作ったList<int>
list.Where(value => { return value % 2 == 0; });

省略ルールその三
処理が一文だけならばreturnと{}を省略できる

//listは事前に作ったList<int>
list.Where(value => value % 2 == 0);

{}が消えて書き方がただの値と同じになったので文末の;も消せます。
(これはラムダ式ってよりC#のルール)

最初の例になりましたね。
省略していない時と比べて大分すっきりしましたね。

どうしてこいつ使うのか?

そらまぁ究極論楽だからですが(´・ω・`)
どういうところが楽かってのを書いていきましょうか。

ラムダ式を使わない場合処理を渡すためにはデリゲートを使うわけですが、
デリゲートを使うのは前準備が結構めんどくさいです。

static Func<int, bool> testIntBool;
static void Main(string[] args)
{
    testIntBool += Test;
    testIntBool(52);
}
static bool Test(int num)
{
    return num % 2 == 0;
}

わざわざ変数宣言+メソッド宣言しています。
今回は適当なんでそうでもないですが、
実際使うときにはこの辺りの命名にも頭を悩ませる必要があります。
そうなると二つも頭を悩ます要素が増えるわけです。

ラムダ式は匿名メソッドと言って
名前のないメソッドです。
なので命名を考える必要がありません。(楽だ)

他にもデリゲートはFuncとか使わずdelegateキーワードを使って自前で作ることもできます。

delegate bool testDelegate(int num);
static void Main(string[] args)
{
    var test = new testDelegate(Test);
    test(52);
}
static bool Test(int num)
{
    return num % 2 == 0;
}

普通のデリゲートを使う場合はこんなに手間がかかります。

これだけのことやってようやくできる処理を渡すという行為が

value => value % 2 == 0

この一文だけでできるラムダ式がどれだけ楽かなんとなくわかってもらえたかと思います。

あとがき

今回はC#ラムダ式でした。
C#やってて言語理解的に詰まるとしたら
ここなのではないでしょうか?

今までは値でしかやり取りしてなかったのに
急に処理でやり取りし始めますからね。
(今まで日本語でしゃべってたのに急に英語でしゃべりだしたみたいな)

今回は使い方というか書き方と意味、
そして他のやり方と比べてというところに重きを置いて書きました。

ラムダ式
値と同じような感じで処理を書くやり方
って感じで覚えとけば大きく外すことはないと思います。
(和訳まではいかずとも「Youはvery kindね!」ぐらいには近づくと思います)

それでは今回はこの辺でノシ