2005年9月14日水曜日

LINQの裏にあるラムダ式

(どっとねっとふぁんBlog経由)

PDCでLINQことLanguage Integrated Queryのアナウンスとデモがあったそうだ。
http://msdn.microsoft.com/netframework/future/linq/default.aspx

ちょっとサンプルを見てみよう。サンプルは http://msdn.microsoft.com/vcsharp/future/linqsamples/ にある。
public void Linq1() {
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

var lowNums =
from n in numbers
where n < 5
select n;

Console.WriteLine("Numbers < 5:");
foreach (var x in lowNums) {
Console.WriteLine(x);
}
}

実行結果は
Numbers < 5:
4
1
3
2
0


なんだこれ、コード中にSQLみたいのが。
気を落ち着けて、overview (http://download.microsoft.com/download/c/f/b/cfbbc093-f3b3-4fdb-a170-604db2e29e99/linq%20project%20overview.doc) を読む。
上記コードだとvariant型みたいなのが使われていて良くわからないが(追記:型推論。C# 3.0の機能らしい。)、型を明確に書き直すとこうなるらしい。
IEnumerable<int> lowNums =
from n in numbers
where n < 5
select n;

しかも、上の書き方はシンタックスシュガーらしく、下の書き方と等価らしい。
IEnumerable<int> lowNums = numbers
.Where(n => n < 5)
.Select(n => n);

さらに、下のように分けて書くこともできる。
Func<int, bool> filter = n => n < 5;
Func<int, int> project = n => n;
IEnumerable<int> lowNums = numbers
.Where(filter)
.Select(project);

で、これをC#2.0風に書くとこうなる。
Func<int, bool> filter = delegate (int n)
{
return (n < 5);
};
Func<int, int> project = delegate (int n)
{
return n;
};
IEnumerable<int> lowNums = numbers
.Where(filter)
.Select(project);

ようするにクロージャで実現されているということ。
LINQとは視点がずれるけど、C# 3.0だとコレクションクロージャメソッドも書き方が変わるな。
//rubyだと managers = employees.select {|e| e.manager?}
managers = employees.FindAll(e => e.IsManager);

こうですか?わかりません!

0 件のコメント:

コメントを投稿