悩んでる人C#のListって検索メソッドがいっぱいあって、どれを使えばいいか全然わからない…



FindとFindAll、FindIndexって何が違うの?FirstOrDefaultとはどう使い分けるの?
C#のListには検索メソッドがたくさん用意されていて、最初は何を使えばいいか迷いますよね。
実は、それぞれのメソッドには明確な「使いどころ」があります。
本記事では、C#のList.Find()の基本的な使い方から、FindAll・FindIndex・FirstOrDefaultとの違いまで、サンプルコードと図解でわかりやすく解説します。
「なんとなく動くコードは書けるけど、これで合ってるか不安…」という方もぜひ参考にしてみてください!
- List.Find() の基本的な書き方とラムダ式の読み方
- Find / FindAll / FindIndex / FindLast の違い
- 見つからない場合の戻り値と注意点
- カスタムクラスのリストを検索する実践例
- FirstOrDefault との使い分けポイント


- システムエンジニア10年目
- 会社員3年⇒フリーランス7年目
- 保険系 / 物流系 / 鉄道系 / 小売系などのシステム開発に従事
- プログラミング講師
List.Find()とは?基本を図解でおさえよう


List.Find() は、リストの中から条件に合う最初の要素を1件だけ返すメソッドです。
先頭の要素から順番に確認していき、条件を満たした瞬間にそこで検索をストップします。


「リストの中から条件に合う最初の1件だけ返す」のがFindメソッドです。全件ほしい場合はFindAll()を使います!
List<T> クラスが持つメソッドなので、引数には Predicate\(条件を判定するデリゲート)を渡します。
実際のコードではラムダ式を使うのが一般的なので、その書き方も含めて次のセクションで解説します。
Find() の基本的な書き方


数値リストから検索する
using System.Collections.Generic;
var list = new List<int> { 1, 2, 3, 7, 8, 9 };
// 偶数を前から検索して、最初に見つかった1件を返す
int result = list.Find(n => n % 2 == 0);
Console.WriteLine(result); // 出力:22
ラムダ式 n => n % 2 == 0 の意味は「要素nが偶数かどうかを返す」です。
条件が true になった最初の要素が返されるので、8は返されない点に注意しましょう。
ラムダ式 => の左が「要素」、右が「条件式」と覚えれば読めるようになりますよ!
文字列リストから検索する
var fruits = new List<string> { "りんご", "バナナ", "オレンジ", "メロン" };
// 4文字以上の文字列を前から検索
string result = fruits.Find(s => s.Length >= 4);
Console.WriteLine(result); // 出力:オレンジオレンジ
Findメソッドは先頭から順番に検索するため、計算量は O(n) です。リストが大きいほど検索時間が伸びます。
要素数が多く、要素が昇順に並んでいる場合は BinarySearch() の使用も検討しましょう。
見つからない場合の戻り値と注意点


Findメソッドは要素が見つからなかった場合、型の既定値(default value) を返します。
参照型(stringやクラス)なら null、数値型なら 0 が返ってくるため、必ずnullチェックを行いましょう。
| リストの型 | 見つかった場合 | 見つからない場合 |
|---|---|---|
List<int>(数値) | その値 | 0(型の既定値) |
List<string>(文字列) | その文字列 | null |
List<クラス>(参照型) | そのオブジェクト | null |
List<構造体>(値型) | その構造体 | ゼロ初期化した構造体 |
var fruits = new List<string> { "りんご", "バナナ" };
string? result = fruits.Find(s => s == "みかん");
// nullチェックを必ず行う
if (result != null)
{
Console.WriteLine($"見つかりました:{result}");
}
else
{
Console.WriteLine("見つかりませんでした");
}見つかりませんでした
数値型のリストで値 0 が存在する場合、「見つからなかった」のか「0が見つかった」のかを区別できません。
このケースでは FindIndex() を使い、インデックスが -1 かどうかで判定するのがベターです。



数値のリストで0が戻ってきたとき、見つからなかったのか、実際に0があるのか区別できないの?
その通りです!そんなときはFindIndex()を使って戻り値が-1かどうかを確認しましょう!
FindAll():条件に合う全件を取得


FindAll() は、条件に合う要素を全件取得したいときに使います。
戻り値は List<T> なので、そのままforeachでループ処理できて便利です。
| メソッド | 取得件数 | 戻り値 |
|---|---|---|
| Find() | 最初の1件のみ | T型の要素 |
| FindAll() | 全件 | List\<T> |
var numbers = new List<int> { 1, 2, 3, 7, 8, 9 };
// 偶数をすべて取得
List<int> results = numbers.FindAll(n => n % 2 == 0);
foreach (var n in results)
{
Console.WriteLine(n);
}2
8
FindAll()は要素が見つからなくても null は返しません。
空のList(Count = 0)が返るため、nullチェックは不要です。
if (results.Count > 0) で件数チェックするだけでOKです。
応用として、部分一致でフィルタリングもできますよ
var names = new List<string> { "田中一郎", "山田花子", "田中二郎", "鈴木太郎" };
// "田中"を含む要素をすべて取得
List<string> results = names.FindAll(s => s.Contains("田中"));
foreach (var name in results)
{
Console.WriteLine(name);
}田中一郎
田中二郎
「1件だけほしい → Find()」「全件ほしい → FindAll()」と使い分ければバッチリです!
FindIndex():インデックスを取得


FindIndex() は、条件に合う最初の要素のインデックス(位置番号)を返します。
要素の値そのものではなく「何番目にあるか」を知りたいときに使います。


var list = new List<int> { 1, 2, 3, 7, 8, 9 };
// 偶数の最初のインデックスを取得
int index = list.FindIndex(n => n % 2 == 0);
Console.WriteLine(index); // 出力:1(2番目の要素)
// 見つからない場合は -1 が返る
int notFound = list.FindIndex(n => n > 100);
Console.WriteLine(notFound); // 出力:-11
-1
数値型のリストで「0が存在するかどうか」を判定したいとき、Find()では0と未発見を区別できません。
FindIndex()で戻り値が -1 かどうかを確認すれば、確実に判定できます。
FindLast() / FindLastIndex():後ろから検索


FindLast() と FindLastIndex() は、リストの末尾から検索します。
重複データがある場合に「最後に見つかった方」を取得したいときに便利です。


var numbers = new List<int> { 1, 2, 3, 7, 8, 9 };
// 後ろから偶数を検索して最後の1件を返す
int lastEven = numbers.FindLast(n => n % 2 == 0);
Console.WriteLine(lastEven); // 出力:8
// 後ろから偶数を検索してインデックスを返す
int lastEvenIndex = numbers.FindLastIndex(n => n % 2 == 0);
Console.WriteLine(lastEvenIndex); // 出力:48
4
カスタムクラスのリストを検索する


実務でよく使うのが、カスタムクラスをリストに格納して検索するパターンです。
ユーザー情報や商品データなど、複数のプロパティを持つオブジェクトをFind()で絞り込む方法を見ていきましょう。


// 商品クラスの定義
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}// リストを作成
var products = new List<Product>
{
new Product { Id = 1, Name = "りんご", Price = 150 },
new Product { Id = 2, Name = "バナナ", Price = 100 },
new Product { Id = 3, Name = "メロン", Price = 800 },
};
// IDで検索(1件)
Product? target = products.Find(p => p.Id == 2);
if (target != null)
{
Console.WriteLine($"商品名:{target.Name}、価格:{target.Price}円");
}
// 500円以上の商品をすべて取得
List<Product> expensiveList = products.FindAll(p => p.Price >= 500);
foreach (var p in expensiveList)
{
Console.WriteLine($"{p.Name}:{p.Price}円");
}商品名:バナナ、価格:100円
メロン:800円
ラムダ式の左辺でリストの要素を受け取り(例:p)、右辺でプロパティにアクセスして条件を書きます(例:p.Id == 2)。
参照型なので戻り値は null になる可能性があり、nullチェックを忘れずに。
FirstOrDefault との使い分け


Find() と FirstOrDefault() はよく似ていますが、重要な違いがあります。
Find() はList\<T>専用のメソッドで、FirstOrDefault() はLINQの拡張メソッドです。
| メソッド | 種別 | 特徴 |
|---|---|---|
| Find() | List専用 | List\<T> のメソッド。パフォーマンス若干有利 |
| FirstOrDefault() | LINQ | IEnumerable\<T> の拡張メソッド。List以外でも使用可能 |
| First() | LINQ | 見つからない場合に 例外が発生。必ず存在する確信がある場合のみ使用 |
var list = new List<int> { 1, 2, 3, 7, 8, 9 };
// Find:List<T> のメソッド
int result1 = list.Find(n => n > 5); // 7
// FirstOrDefault:LINQ の拡張メソッド
int result2 = list.FirstOrDefault(n => n > 5); // 7
// First:見つからないと例外が発生する!
// int result3 = list.First(n => n > 100); // ← InvalidOperationException!First() は要素が必ず存在すると確信できる場合のみ使います。
「見つからないかもしれない」という場面では FirstOrDefault() か Find() を使いましょう。
実務では予期しない例外の原因になることが多いです。



FindとFirstOrDefaultどっちを使えばいいの?
対象がListなら Find()、LINQを使った処理と組み合わせたい場合はFirstOrDefault()という感じで覚えておけばOKです!
検索メソッド比較まとめ


これまでに紹介してきた、List検索メソッドをまとめています。
ここで振り返りましょう!!


| メソッド | 戻り値 | 件数 | 見つからない場合 | 使いどころ |
|---|---|---|---|---|
| Find() | T型 | 1件 | 型の既定値(null/0) | 最初の1件が欲しい |
| FindAll() | List\<T> | 全件 | 空のList | 全件まとめて欲しい |
| FindIndex() | int | 1件 | -1 | 位置番号を知りたい |
| FindLast() | T型 | 1件 | 型の既定値(null/0) | 最後の1件が欲しい |
| FindLastIndex() | int | 1件 | -1 | 最後の位置番号を知りたい |
| FirstOrDefault() | T型 | 1件 | 型の既定値(null/0) | LINQ/IEnumerableで統一 |
| First() | T型 | 1件 | 例外が発生! | 必ず存在する確信がある場合 |
まとめ


- Find() は条件に合う最初の1件を返す。見つからない場合は型の既定値(null/0)が返る
- FindAll() は全件をList\<T>で返す。見つからなくても例外は発生せず空のListが返る
- FindIndex() はインデックスを返す。見つからない場合は -1 が返るため存在チェックに使いやすい
- FindLast() / FindLastIndex() は後ろから検索。重複データで最後のものを取りたいときに使う
- Find() vs FirstOrDefault() は対象がListなら基本的にFind()、LINQ処理と組み合わせるならFirstOrDefault()
- 参照型リストのFind()結果は必ずnullチェックを忘れずに!
- 数値型リストで「0かどうか」を判定する場合は FindIndex() を使って -1 チェックするのがベター
Findメソッドはラムダ式と組み合わせることで、非常にシンプルに検索処理を書けます。まずはFind()とFindAll()の2つをしっかり使えるようになると、コードがグッとスッキリしますよ!
C#のList検索をマスターすると、foreach + if の組み合わせでゴリゴリ書いていたコードをスッキリ1行で表現できます。
次のステップとして、LINQのWhereやSelectにも挑戦してみましょう!
