2012/07/25

ラムダ式の自分なりの解釈

先日の記事でFuncデリゲートが苦手と書いたけど、Funcデリゲート自体よりラムダ式が苦手だったりするので改めて自分用に自分なりの解釈をしておこうと思った。Funcデリゲート自体はラムダ式のおまけだとだと思ってしまえばそれまでだし…。

基本的にLINQでの使用が多いラムダ式ですが、MSDNによると「ラムダ式は式とステートメントを含めることができる匿名関数であり、デリゲート型または式ツリー型を作成するために使用できます。 」(引用元:ラムダ式 (C# プログラミング ガイド))とのこと。はぁ…、まずは匿名関数(匿名メソッド)が分かってないと駄目ってことですよね。

というわけでまずは匿名メソッドを解釈してみます。まぁ読んで字のごとく名前の無いメソッドで、C#2.0から登場した機能です。正直、C#3.0でラムダ式というかLINQが登場するまでその存在をほとんど忘れてました。だっていまいち利便性が分からなかったし、使いどころがピンとこなかったから。放置してたらこの有様です。

では早速解説を…と思ったんですが、この匿名メソッド、なんだか難しく考えない方が良さそうな気がします。まぁ簡単に(ほんとうに簡単に)「デリゲートを使用する際に外部に書き出してたメソッドをインラインで書けるようにしちゃおうというもの」と考えるのが良さそうです。

デリゲートとはとか言い出すと切りがなくなるのでそれは勘弁してもらって、以下のようなサンプルがあるとします。

static void Main(string[] args)
{
var thread1 = new Thread(new ThreadStart(Plus));
var thread2 = new Thread(new ThreadStart(Minus));
thread1.Start();
thread2.Start();
}

static void Plus()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i.ToString());
Thread.Sleep(250);
}
}

static void Minus()
{
for (int i = 100; i >= 0; i--)
{
Console.WriteLine(i.ToString());
Thread.Sleep(500);
}
}

このサンプルを匿名メソッドを利用する形に変更すると以下のようになります。PlusとMinusそれぞのメソッドがインラインで表現されてるのが分かると思います。ついでにスコープ外の参照ができることも確認できると思います。

static void Main(string[] args)
{
var message1 = "20の倍数です(スコープ外も参照できます)";

var thread1 = new Thread
(delegate()
{
for (int i = 1; i < 100; i++)
{
Console.WriteLine(i.ToString());
Thread.Sleep(250);

if (i % 20 == 0)
{
Console.WriteLine(message1);
}
}
});

var thread2 = new Thread
(delegate()
{
for (int i = 100; i >= 1; i--)
{
Console.WriteLine(i.ToString());
Thread.Sleep(500);

if (i % 20 == 0)
{
Console.WriteLine(message1);
}
}
});

thread1.Start();
thread2.Start();
}

改めて見ても使いどころがピンときません。このサンプルももうちょっと他で使えるサンプルをと思ってたけどこんなのしか思いつかなかったし…。こんなんじゃ本質を理解していると言えない気がするけどラムダ式への通過点ということで…。

なんだか長くなりそうなので本命のラムダ式はまた次回で!


pagetop