全体から一部を取り出す

プログラミングC# 第6版 8.3.7


全部は必要なくて例えば先頭から3件だけ処理したいとかいう場合にTakeメソッドを使います。

using System;
using System.Linq;

class Program {
    static void Main() {
        int[] nums = new int[] {1,2,3,4,5,6,7};
        
        // 先頭から3件まで取得
        var ret = nums.Take(3);
        
        foreach(var n in ret) {
            Console.WriteLine("{0}",n);
        }
    }
}
$ main
1
2
3

先頭から1件だけ欲しい場合はFirstメソッドが使えます。FirstはTakeと違って配列ではなく要素そのものが返ってきます。

class Program {
    static void Main() {
        string[] strs = new string[] {"foo","bar","baz"};
        
        // 先頭ひとつ
        var ret = strs.First();
        
        // 配列じゃなく、要素が返ってくるのでそのまま出力する
        Console.WriteLine("{0}",ret);
    }
}
$ main
foo

ただしFirstは要素が無い場合に使用すると例外をスローします。

$ main

ハンドルされていない例外: System.InvalidOperationException: シーケンスに要素が含まれていません
   場所 System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   場所 Program.Main()

要素が無い場合に例外を発生させるのではなく、null等のデフォルト値を返したい場合はFirstOrDefaultメソッドが使えます。

class Program {
    static void Main() {
        string[] strs = new string[] {};
        
        // 要素が無い場合にデフォルト値が入る
        var ret = strs.FirstOrDefault();
        
        if ( ret != null ) {
            Console.WriteLine("{0}",ret);
        }
    }
}

また、Firstに似たSingleというメソッドもあります。こちらは要素が1つ以外の場合に例外をスローするので、要素が必ず1つであることを保障します。

using System;
using System.Linq;

class Program {
    static void Main() {
        // 要素二つ
        string[] strs = new string[] {"foo","bar"};
        
        // 要素が1つのはず。それ以外は例外
        var ret = strs.Single();
        
        Console.WriteLine("{0}",ret);
    }
}
$ main

ハンドルされていない例外: System.InvalidOperationException: シーケンスに複数の要素が含まれています
   場所 System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   場所 Program.Main()

SingleOrDefaultメソッドもあってそっちは要素が0か1つであることを保障します。

FirstとSingleの使い分けですが、あるクエリ式の結果が必ず一つのはずってときにSingleを使って堅牢にしておくって感じですかね。