C# Linq


Linqとは

C#の統合言語型クエリ
コレクションの要素を処理するメソッドがある。

Linqを使用するとfor文やforeach文、if文を使用しなくても
処理を書くことが出来る場合があります。
そのため、全体のライン数とネストを減らして記載することが出来ます。
ライン数やネストが減ると可読性向上にも繋がります。

Linqを使用した処理と使用しない処理での違いを検証

今回はそれぞれの動作を確認しつつ、Listに格納したデータを処理してみます。
以下に記載しているサンプルソースは以下のリストを宣言しており、以下の宣言はサンプルソースから省いています。

sample.cs
            List<int> source = new List<int>() { 1, 2, 3, 4, 5, 6 };
            List<int> target = new List<int>();

また、foreachはListクラスのForEachメソッドを使用して、以下のように書き換えています。

sample.cs
            foreach(int num in source)
            {
                Console.WriteLine(num);
            }
sample.cs
            source.ForEach(delegate (int num) { Console.WriteLine(num); });

  • Where

WhereはList内から条件に一致したデータを抽出します。

Linqを使わない場合

sample.cs
            foreach (int num in source)
            {
                //sourceから5未満のリストを作成
                if(num < 5)
                {
                    target.Add(num);
                }
            }
            //sourceを出力
            Console.WriteLine("source");
            foreach (int num in source)
            {
                Console.WriteLine(num);
            }
            //targetを出力
            Console.WriteLine("target");
            foreach (int num in target)
            {
                Console.WriteLine(num);
            }

Linqを使った場合

sample.cs
            //sourceから5未満のリストを作成
            target = source.Where(num => num < 5).ToList();

            //sourceを出力
            Console.WriteLine("source");
            source.ForEach(delegate (int num) { Console.WriteLine(num); });

            //targetを出力
            Console.WriteLine("target");
            target.ForEach(delegate (int num) { Console.WriteLine(num); });

出力結果はどちらも以下のようになります。

  • Select

SelectはList内の要素を計算した結果を出力できます。
リストの値に

Linqを使わない場合

sample.cs
            List<int> source = new List<int>() { 1, 2, 3, 4, 5, 6 };
            List<int> target = new List<int>();

            foreach (int num in source)
            {
                //5を乗算した値を追加
                target.Add(num * 5);
            }

            foreach (int num in target)
            {
                Console.WriteLine(num);
            }

Linqを使った場合

sample.cs
            target = source.Select(num => num * 5).ToList();

            target.ForEach(delegate (int num) {Console.WriteLine(num); });

出力結果はどちらも以下のようになります。

Selectでは以下のようにして、インデックスを抜き出すこともできます。

sample.cs
            source.Select((data, index) => new { Data = data, Index = index })
  • その他の便利な使い方

foreachとwhichを組み合わせるとforeachの中でif文を記載しなくても、同様の処理が出来たりします。
リストの値を出力する処理です。

sample.cs
            foreach (int data in source.Where(tmpData => (tmpData == 1) || (tmpData == 3)))
            {
                Console.WriteLine(data);
            }

組み合わせると以下のような処理もできたりします。
0番目から偶数位置に格納されているリストの値を出力する処理です。
ここまですると逆に複雑な気もします。

sample.cs

            source.Select((data, index) => new { Data = data, Index = index })
                .Where(SelectData => (SelectData.Index == 0 || SelectData.Index % 2 == 0)).ToList()
                .ForEach(num => { Console.WriteLine(num.Data); });

  • 終わりに

Linqのメソッドを紹介してみました。
Linqはぱっと見でわかりにくい場合もあるので、なるべくコメントは書いた方がよさそうですね
他にもLinqの便利なメソッドはあるので、また時間があるときに書きます。