2014年6月1日日曜日

C#応用 – LINQプログラミング 2




さて、C#応用 LINQプログラミング第2回である。



LINQことはじめ
LINQでは、一連の汎用に利用できる「標準クエリ演算子」が定義される。

この標準クエリ演算子により、.NETベースのプログラミング言語内で

宣言型の直接的手法を使って以下の表現が行える。

  • 一括演算
  • フィルタ演算
  • プロジェクション演算
  • etc.

標準クエリ演算子
標準クエリ演算子ではIEnumerable<T>ベースのすべての情報ソースに

クエリ機能が適用できる。

IEnumerableインタフェースは、配列、リスト、Dictionaryを列挙できる。

LINQの採用によりサードパーティによる様々な標準クエリ演算子のセットを

追加できるようになる。 CSV、JSONなど

もちろん、これらは独自の実装に自由に置き換えることができる。

まずはサンプル
標準クエリ演算子を利用する簡単なプログラム

    class Program
    {
        static void Main(string[] args)
        {
            string[] places = {
                                  "東京", "大阪", "名古屋",
                                  "岐阜", "札幌", "旭川"
                              };

            IEnumerable<string> result = from p in places
                                         where p.Length == 2
                                         orderby p
                                         select p.Substring(0, 1);

            foreach(var place in result)
            {
                Console.WriteLine(place);
            }

            // すぐに終了しないように、キー入力待ち
            Console.ReadKey();
        }
    }

このようなSQL系の構文を「クエリ式」と呼ぶ。

上のプログラムの実行結果は次の通り。



places の中から2文字のものを取り出し

50音順に並び替えつつ

最初の1文字を出力している



言語統合
先のサンプルは、クエリ構文となっている。

IEnumerable<string> result = from p in places
                                         where p.Length == 2
                                         orderby p
                                         select p.Substring(0, 1);

これをメソッド構文で書くこともできる。ちなみに、こちらの方が本家である。

IEnumerable<string> result = places
                                         .Where(a => a.Length == 2)
                                         .OrderBy (a => a)
                                         .Select(a => a.Substring(0, 1));

実はサンプルをコンパイルすると

クエリ式はコンパイラでは以下のように変換される。

            string[] places = {
                                  "東京", "大阪", "名古屋",
                                  "岐阜", "札幌", "旭川"
                              };
      IEnumerable<string> result = places
                                         .Where(a => a.Length == 2)
                                         .OrderBy (a => a)
                                         .Select(a => a.Substring(0, 1));

            foreach(var place in result)
            {
                Console.WriteLine(place);
            }

結局、クエリ構文は上記のような「拡張メソッド」に変換されているのである。


今日の名言
木を見て森を見ないのはよくあることだ。同じように、広い範囲を見るのに夢中になり
未来の利益にばかり目を奪われていると、現在手元にある機会はおろか、せっかく
手に入る利益も目に入らなくなる。人生はただでさえ短いのに、時間を浪費すると
更に短くなる。
                                サミュエル・ジョンソン

毎日毎日をきっぱりと終了せよ・・・。あなたは全力を尽くした。確かにへまもやったし、
馬鹿なこともしでかした。そんなことはできるだけ早く忘れよう。明日は新しい日だ。
明日をつつがなく、静かにはじめるのだ。
                                ラルフ・ワルド・エマーソン