C#のwhereとは?LINQのWhereメソッドの使い方を初心者向けにサンプルコードで徹底解説
はじめに
C#のwhereは、データを条件で絞り込むときによく登場する重要なキーワードです。
特に初心者が最初につまずきやすいのが、LINQで使うWhereメソッドです。
C#var result = numbers.Where(x => x >= 10);
このようなコードを見て、「whereとは何か」「x => x >= 10は何をしているのか」「結果は何が返ってくるのか」が分からず戸惑う人は多いです。
C#のwhereには、主に次のような使い方があります。
C#// LINQのWhereメソッド
var adults = users.Where(user => user.Age >= 20);
// クエリ構文のwhere句
var adultsQuery =
from user in users
where user.Age >= 20
select user;
// ジェネリック制約のwhere
public class Repository<T> where T : class
{
}
同じwhereという言葉でも、使われる場面によって意味が異なります。
この記事では、特に使用頻度の高いLINQのWhereメソッドを中心に、C#のwhereの基本、書き方、複数条件、注意点、よくあるエラー、実践的なサンプルコードまで初心者向けに解説します。
1. C#のwhereとは?まず押さえるべき基本
C#でwhereと聞いたとき、まず理解しておきたいのは「条件を指定するために使われることが多い」という点です。
ただし、C#には複数のwhereがあります。
代表的なのは次の3つです。
C#// 1. LINQのWhereメソッド
var result = list.Where(x => x > 10);
// 2. クエリ構文のwhere句
var result =
from x in list
where x > 10
select x;
// 3. ジェネリック制約のwhere
public void Sample<T>() where T : class
{
}
この記事で中心的に扱うのは、1つ目のLINQのWhereメソッドです。
LINQのWhereメソッドは、配列やリストなどのコレクションから、条件に合う要素だけを取り出すために使います。
1-1. C#で「where」が使われる主な場面
C#でwhereが使われる主な場面は、次のとおりです。
1つ目は、LINQのWhereメソッドです。
C#var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
このコードでは、数値リストから偶数だけを取り出しています。
2つ目は、LINQのクエリ構文で使うwhere句です。
C#var evenNumbers =
from n in numbers
where n % 2 == 0
select n;
これはSQLに近い見た目でLINQを書く方法です。
3つ目は、ジェネリック制約のwhereです。
C#public class Service<T> where T : class
{
}
この場合のwhereは、Tに指定できる型を制限するために使います。
つまり、同じwhereでも「データを絞り込むためのwhere」と「型を制限するためのwhere」があるということです。
1-2. LINQのWhereメソッドとは
LINQのWhereメソッドは、コレクションの中から条件に一致する要素だけを取り出すメソッドです。
たとえば、次のような数値リストがあるとします。
C#var numbers = new List<int> { 5, 10, 15, 20, 25 };
この中から「15以上の数値だけ」を取り出したい場合、Whereを使って次のように書けます。
C#var result = numbers.Where(n => n >= 15);
foreach (var number in result)
{
Console.WriteLine(number);
}
実行結果は次のようになります。
C#15
20
25
Whereの中に書いているn => n >= 15は、「要素nが15以上かどうかを判定する条件」です。
条件に合う要素だけが、結果として取り出されます。
1-3. SQLのWHERE句との違い
SQLにもWHERE句があります。
SQLSELECT *
FROM Users
WHERE Age >= 20;
SQLのWHERE句は、データベースのテーブルから条件に合う行を絞り込むために使います。
一方、C#のLINQのWhereメソッドは、配列、List、オブジェクトの一覧などから条件に合う要素を絞り込むために使います。
C#var adults = users.Where(user => user.Age >= 20);
考え方は似ていますが、書く場所と対象が違います。
SQLのWHEREはデータベースに対する命令です。
C#のWhereはC#コード上でコレクションを絞り込むためのメソッドです。
ただし、Entity Frameworkなどを使っている場合、C#で書いたWhereがSQLのWHERE句に変換されることもあります。
C#var adults = dbContext.Users.Where(user => user.Age >= 20);
このようなコードは、最終的にデータベース側ではWHERE Age >= 20のようなSQLとして実行される場合があります。
1-4. where句とWhereメソッドの違い
C#のLINQには、大きく分けて「メソッド構文」と「クエリ構文」があります。
メソッド構文で使うのがWhereメソッドです。
C#var result = numbers.Where(n => n > 10);
クエリ構文で使うのがwhere句です。
C#var result =
from n in numbers
where n > 10
select n;
どちらも「条件に合う要素だけを取り出す」という目的は同じです。
違いは書き方です。
メソッド構文は、C#のメソッドチェーンとして書きます。
C#var result = numbers
.Where(n => n > 10)
.OrderBy(n => n);
クエリ構文は、SQLに近い形で書きます。
C#var result =
from n in numbers
where n > 10
orderby n
select n;
実務ではメソッド構文のWhereメソッドがよく使われます。
ただし、複雑な結合やグループ化ではクエリ構文の方が読みやすい場合もあります。
1-5. ジェネリック制約のwhereとの違い
C#には、LINQとは別にジェネリック制約で使うwhereもあります。
C#public class Repository<T> where T : class
{
}
このwhereは、データを絞り込むためのものではありません。
型Tに指定できる条件を制限するためのものです。
たとえば、次のコードではTは参照型でなければならない、という制約を付けています。
C#public void Save<T>(T item) where T : class
{
Console.WriteLine(item);
}
よく使うジェネリック制約には次のようなものがあります。
C#where T : class // 参照型のみ
where T : struct // 値型のみ
where T : new() // 引数なしコンストラクタが必要
where T : BaseClass // 特定の基底クラスを継承している型のみ
where T : IInterface // 特定のインターフェースを実装している型のみ
LINQのWhereは「データの絞り込み」です。
ジェネリック制約のwhereは「型の制限」です。
この2つはまったく別の用途なので、混同しないようにしましょう。
2. LINQのWhereメソッドでできること
LINQのWhereメソッドを使うと、コレクションから条件に合う要素だけを簡単に取り出せます。
たとえば、次のような場面で使えます。
C#// 20歳以上のユーザーだけを取り出す
var adults = users.Where(user => user.Age >= 20);
// 在庫がある商品だけを取り出す
var availableProducts = products.Where(product => product.Stock > 0);
// 名前に「田中」を含むデータだけを取り出す
var tanakaUsers = users.Where(user => user.Name.Contains("田中"));
if文でも同じような処理は書けますが、Whereを使うと短く読みやすいコードにできます。
2-1. コレクションから条件に合う要素だけを取り出す
Whereメソッドの基本的な役割は、コレクションから条件に合う要素だけを取り出すことです。
C#var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
foreach (var number in evenNumbers)
{
Console.WriteLine(number);
}
実行結果は次のとおりです。
C#2
4
6
n % 2 == 0は、「2で割った余りが0かどうか」を判定しています。
つまり偶数だけを取り出しています。
2-2. 配列・List・オブジェクト一覧を絞り込む
Whereは、配列にもListにも使えます。
配列の例です。
C#int[] numbers = { 3, 8, 12, 15, 20 };
var result = numbers.Where(n => n >= 10);
List<string>の例です。
C#var names = new List<string> { "Alice", "Bob", "Charlie" };
var result = names.Where(name => name.Length >= 5);
オブジェクト一覧にも使えます。
C#var users = new List<User>
{
new User { Name = "太郎", Age = 18 },
new User { Name = "花子", Age = 25 },
new User { Name = "健一", Age = 30 }
};
var adults = users.Where(user => user.Age >= 20);
このように、Whereは単純な数値や文字列だけでなく、自分で作ったクラスの一覧にも使えます。
2-3. 条件式にはboolを返す処理を書く
Whereメソッドの条件には、trueまたはfalseを返す処理を書きます。
C#var result = numbers.Where(n => n > 10);
この場合、n > 10はbool型の結果を返します。
C#10 > 5 // true
3 > 10 // false
Whereは、条件がtrueになった要素だけを残します。
そのため、次のようにboolを返さない式を書くとエラーになります。
C#// エラーになる例
var result = numbers.Where(n => n + 10);
n + 10は数値を返す式であり、trueまたはfalseを返していません。
正しくは次のように書きます。
C#var result = numbers.Where(n => n + 10 > 20);
この場合は、n + 10 > 20がboolを返すため、Whereの条件として使えます。
2-4. Whereメソッドの基本構文
Whereメソッドの基本構文は次のとおりです。
C#コレクション.Where(要素 => 条件式)
具体例は次のようになります。
C#var result = numbers.Where(number => number >= 10);
各部分の意味は次のとおりです。
C#numbers
絞り込み対象のコレクションです。
C#number
コレクションから1つずつ取り出される要素を表す変数です。
C#number >= 10
その要素を残すかどうかを判定する条件です。
全体としては、「numbersの中から、number >= 10を満たす要素だけを取り出す」という意味になります。
3. C#のWhereメソッドの基本的な使い方
ここからは、C#のWhereメソッドの基本的な使い方をサンプルコードで見ていきます。
Whereを使うには、通常は次の名前空間を読み込んでおきます。
C#using System.Linq;
.NET 6以降のプロジェクトでは、暗黙的なusingによって明示的に書かなくても使える場合があります。
ただし、学習中はWhereが使えないときにusing System.Linq;を確認する習慣を付けるとよいです。
3-1. 数値リストを条件で絞り込むサンプル
まずは数値リストを絞り込む基本例です。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var numbers = new List<int> { 5, 10, 15, 20, 25 };
var result = numbers.Where(n => n >= 15);
foreach (var number in result)
{
Console.WriteLine(number);
}
}
}
実行結果は次のとおりです。
C#15
20
25
n => n >= 15は、「数値nが15以上なら残す」という意味です。
Whereは条件に一致した要素だけを返します。
3-2. 文字列リストを条件で絞り込むサンプル
次に、文字列リストを絞り込む例です。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var names = new List<string> { "Alice", "Bob", "Charlie", "David" };
var result = names.Where(name => name.Length >= 5);
foreach (var name in result)
{
Console.WriteLine(name);
}
}
}
実行結果は次のようになります。
C#Alice
Charlie
David
この例では、文字数が5文字以上の名前だけを取り出しています。
文字列の条件では、LengthやContains、StartsWith、EndsWithなどをよく使います。
C#var result1 = names.Where(name => name.Contains("a"));
var result2 = names.Where(name => name.StartsWith("A"));
var result3 = names.Where(name => name.EndsWith("d"));
3-3. オブジェクトのプロパティを条件に絞り込むサンプル
実務では、オブジェクトの一覧をWhereで絞り込むことが多いです。
次の例では、ユーザー一覧から20歳以上のユーザーだけを取り出します。
C#using System;
using System.Collections.Generic;
using System.Linq;
class User
{
public string Name { get; set; } = "";
public int Age { get; set; }
}
class Program
{
static void Main()
{
var users = new List<User>
{
new User { Name = "太郎", Age = 18 },
new User { Name = "花子", Age = 25 },
new User { Name = "健一", Age = 30 }
};
var adults = users.Where(user => user.Age >= 20);
foreach (var user in adults)
{
Console.WriteLine($"{user.Name}: {user.Age}歳");
}
}
}
実行結果は次のとおりです。
C#花子: 25歳
健一: 30歳
user.Age >= 20のように、オブジェクトのプロパティを条件にできます。
3-4. foreachで結果を取り出す方法
Whereの結果は、そのままforeachで取り出せます。
C#var result = numbers.Where(n => n >= 10);
foreach (var number in result)
{
Console.WriteLine(number);
}
Whereの戻り値は、基本的に「条件に合う要素の集まり」です。
そのため、1つの値として扱うのではなく、複数の要素として処理します。
C#foreach (var item in result)
{
// 条件に一致した要素を1つずつ処理する
}
初心者がよく間違えるのは、Whereの結果を単一の要素だと思ってしまうことです。
C#// 間違いやすい考え方
var user = users.Where(u => u.Id == 1);
このuserには、1人のユーザーではなく、条件に合うユーザーの集まりが入ります。
1件だけ取得したい場合は、FirstOrDefaultなどを使います。
C#var user = users.FirstOrDefault(u => u.Id == 1);
3-5. ToList・ToArrayで結果をリストや配列に変換する方法
Whereの結果をListとして使いたい場合は、ToListを使います。
C#var resultList = numbers
.Where(n => n >= 10)
.ToList();
配列として使いたい場合は、ToArrayを使います。
C#var resultArray = numbers
.Where(n => n >= 10)
.ToArray();
たとえば、次のように書けます。
C#var numbers = new List<int> { 1, 2, 3, 4, 5 };
List<int> evenList = numbers
.Where(n => n % 2 == 0)
.ToList();
int[] evenArray = numbers
.Where(n => n % 2 == 0)
.ToArray();
Whereだけでは、結果はIEnumerable<T>として扱われることが多いです。
後続処理でList<T>が必要な場合は、ToListで変換しましょう。
4. ラムダ式を使ったWhereの書き方
Whereメソッドを理解するうえで重要なのが、ラムダ式です。
Whereでは次のような書き方をよく使います。
C#var result = numbers.Where(x => x > 10);
このx => x > 10がラムダ式です。
初心者には少し見慣れない形ですが、意味はシンプルです。
「xを受け取り、x > 10かどうかを判定する」という意味です。
4-1. ラムダ式「x => 条件」の意味
ラムダ式の基本形は次のとおりです。
C#引数 => 処理
Whereで使う場合は、次のように書きます。
C#x => x > 10
これは、次のような処理を短く書いたものだと考えると分かりやすいです。
C#bool IsGreaterThan10(int x)
{
return x > 10;
}
つまり、Whereの中には「この要素を残すかどうかを判定する処理」を渡しているわけです。
C#var result = numbers.Where(x => x > 10);
このコードは、numbersの各要素を1つずつxに入れて、x > 10がtrueになるものだけを残します。
4-2. 引数名は自由に決められる
ラムダ式の引数名は自由に決められます。
次のコードはすべて同じ意味です。
C#var result1 = numbers.Where(x => x > 10);
var result2 = numbers.Where(n => n > 10);
var result3 = numbers.Where(number => number > 10);
どれも「10より大きい数値だけを取り出す」という意味です。
ただし、読みやすさを考えると、意味のある名前を付けるのがおすすめです。
C#var adults = users.Where(user => user.Age >= 20);
このようにuserと書くと、「ユーザー1件を表している」と分かりやすくなります。
商品一覧ならproduct、注文一覧ならorderのように書くと読みやすいです。
C#var expensiveProducts = products.Where(product => product.Price >= 10000);
var recentOrders = orders.Where(order => order.OrderDate >= DateTime.Today);
4-3. 複雑な条件式を書くときの考え方
条件が複雑になる場合でも、基本は「trueなら残す、falseなら除外する」です。
たとえば、20歳以上かつ名前に「田」が含まれるユーザーを取り出す場合は、次のように書きます。
C#var result = users.Where(user => user.Age >= 20 && user.Name.Contains("田"));
条件が長くなる場合は、改行すると読みやすくなります。
C#var result = users.Where(user =>
user.Age >= 20 &&
user.Name.Contains("田") &&
user.IsActive);
さらに複雑な場合は、条件をメソッドに切り出す方法もあります。
C#var result = users.Where(user => IsTargetUser(user));
static bool IsTargetUser(User user)
{
return user.Age >= 20 &&
user.Name.Contains("田") &&
user.IsActive;
}
条件が複雑になりすぎたときは、無理に1行で書かず、読みやすさを優先しましょう。
4-4. 初心者がつまずきやすいラムダ式の読み方
初心者がラムダ式でつまずきやすい理由は、=>の読み方に慣れていないからです。
次のコードを見てみましょう。
C#var result = users.Where(user => user.Age >= 20);
これは次のように読むと分かりやすいです。
C#usersの中の各userについて、user.Age >= 20なら残す
次のコードも同じように読めます。
C#var result = products.Where(product => product.Price < 1000);
これは次の意味です。
C#productsの中の各productについて、product.Price < 1000なら残す
ラムダ式の左側は「1件分のデータ」、右側は「そのデータを残す条件」と考えましょう。
C#user => user.Age >= 20
この場合、userが1件分のデータ、user.Age >= 20が条件です。
5. Whereメソッドで複数条件を指定する方法
Whereメソッドでは、複数の条件を組み合わせることもできます。
よく使うのは次の3つです。
C#&& // AND条件
|| // OR条件
! // NOT条件
条件を組み合わせることで、「20歳以上かつ有効なユーザー」「価格が1000円未満またはセール中の商品」「削除されていないデータ」などを表現できます。
5-1. AND条件を指定する方法
AND条件は、複数の条件をすべて満たす場合に使います。
C#では&&を使います。
C#var result = users.Where(user => user.Age >= 20 && user.IsActive);
このコードは、「20歳以上で、かつ有効なユーザー」を取り出します。
商品一覧の例も見てみましょう。
C#var result = products.Where(product =>
product.Price >= 1000 &&
product.Stock > 0);
このコードは、「価格が1000円以上で、かつ在庫がある商品」を取り出します。
AND条件では、すべての条件がtrueになった要素だけが残ります。
5-2. OR条件を指定する方法
OR条件は、複数の条件のうちどれか1つでも満たせばよい場合に使います。
C#では||を使います。
C#var result = users.Where(user => user.Age < 20 || user.Age >= 65);
このコードは、「20歳未満または65歳以上のユーザー」を取り出します。
商品一覧の例です。
C#var result = products.Where(product =>
product.Price < 1000 ||
product.IsOnSale);
このコードは、「価格が1000円未満、またはセール中の商品」を取り出します。
OR条件では、どれか1つでもtrueなら結果に含まれます。
5-3. NOT条件を指定する方法
NOT条件は、条件を反転したいときに使います。
C#では!を使います。
C#var result = users.Where(user => !user.IsDeleted);
このコードは、「削除されていないユーザー」を取り出します。
user.IsDeletedがtrueなら削除済み、falseなら削除されていないとします。
!user.IsDeletedと書くことで、IsDeletedがfalseのデータだけを取り出せます。
文字列が空でないデータだけを取り出す場合は、次のようにも書けます。
C#var result = names.Where(name => !string.IsNullOrEmpty(name));
このコードは、nullまたは空文字ではない文字列だけを取り出します。
5-4. Whereを複数回つなげて条件を追加する方法
Whereは複数回つなげて書くこともできます。
C#var result = users
.Where(user => user.Age >= 20)
.Where(user => user.IsActive)
.Where(user => !user.IsDeleted);
これは次のコードと同じような意味です。
C#var result = users.Where(user =>
user.Age >= 20 &&
user.IsActive &&
!user.IsDeleted);
どちらを使っても構いません。
条件ごとに意味を分けたい場合は、Whereを複数回つなげると読みやすくなることがあります。
C#var result = users
.Where(user => user.Age >= 20) // 成人
.Where(user => user.IsActive) // 有効
.Where(user => !user.IsDeleted); // 未削除
一方で、短い条件なら1つのWhereにまとめても問題ありません。
5-5. 複数条件を書くときの可読性のコツ
複数条件を書くときは、コードの読みやすさを意識しましょう。
短い条件であれば、1行でも問題ありません。
C#var result = users.Where(user => user.Age >= 20 && user.IsActive);
条件が長くなる場合は、改行した方が読みやすくなります。
C#var result = users.Where(user =>
user.Age >= 20 &&
user.IsActive &&
!user.IsDeleted);
さらに複雑な条件は、変数やメソッドに切り出すのがおすすめです。
C#var result = users.Where(user => IsSearchTarget(user));
static bool IsSearchTarget(User user)
{
return user.Age >= 20 &&
user.IsActive &&
!user.IsDeleted;
}
実務では、コードは書く時間よりも読む時間の方が長くなります。
そのため、Whereの条件式は短く、意味が伝わりやすい形にすることが大切です。
6. クエリ構文のwhere句の使い方
C#のLINQには、メソッド構文のWhereメソッドだけでなく、クエリ構文のwhere句もあります。
クエリ構文は、SQLに近い見た目でコレクション操作を書く方法です。
C#var result =
from user in users
where user.Age >= 20
select user;
このコードは、次のメソッド構文とほぼ同じ意味です。
C#var result = users.Where(user => user.Age >= 20);
6-1. クエリ構文とは
クエリ構文とは、LINQをSQLのような形式で書く構文です。
基本形は次のようになります。
C#var result =
from 要素 in コレクション
where 条件
select 要素;
たとえば、数値リストから10以上の数値を取り出す場合は、次のように書きます。
C#var numbers = new List<int> { 5, 10, 15, 20 };
var result =
from n in numbers
where n >= 10
select n;
fromでコレクションから要素を取り出し、whereで条件を指定し、selectで結果として返す要素を指定します。
6-2. from・where・selectを使った基本形
クエリ構文の基本は、from、where、selectです。
C#var result =
from user in users
where user.Age >= 20
select user;
各部分の意味は次のとおりです。
C#from user in users
usersから1件ずつuserとして取り出します。
C#where user.Age >= 20
20歳以上のユーザーだけを残します。
C#select user
条件に合ったuserを結果として返します。
名前だけを取り出したい場合は、select user.Nameのように書けます。
C#var names =
from user in users
where user.Age >= 20
select user.Name;
この場合、結果はユーザーオブジェクトではなく、名前の一覧になります。
6-3. メソッド構文のWhereとの書き換え例
クエリ構文とメソッド構文は、相互に書き換えられます。
クエリ構文の例です。
C#var result =
from user in users
where user.Age >= 20
select user;
メソッド構文にすると、次のようになります。
C#var result = users.Where(user => user.Age >= 20);
並び替えを追加した例も見てみましょう。
クエリ構文です。
C#var result =
from user in users
where user.Age >= 20
orderby user.Age
select user;
メソッド構文です。
C#var result = users
.Where(user => user.Age >= 20)
.OrderBy(user => user.Age);
変換を追加する場合は、selectとSelectを対応させます。
C#var names =
from user in users
where user.Age >= 20
select user.Name;
C#var names = users
.Where(user => user.Age >= 20)
.Select(user => user.Name);
6-4. クエリ構文とメソッド構文はどちらを使うべきか
クエリ構文とメソッド構文は、どちらを使っても問題ありません。
ただし、実務ではメソッド構文がよく使われます。
C#var result = users
.Where(user => user.Age >= 20)
.OrderBy(user => user.Name)
.Select(user => user.Name);
メソッド構文は、Where、Select、OrderBy、FirstOrDefaultなどをつなげて書きやすいのが特徴です。
一方、クエリ構文は、SQLに慣れている人には読みやすい場合があります。
C#var result =
from user in users
where user.Age >= 20
orderby user.Name
select user.Name;
初心者には、まずメソッド構文のWhereを覚えるのがおすすめです。
そのうえで、クエリ構文も読めるようにしておくと、他人のコードを理解しやすくなります。
7. Whereとよく一緒に使うLINQメソッド
Whereは単体でも便利ですが、ほかのLINQメソッドと組み合わせることでさらに強力になります。
よく一緒に使うメソッドには、次のようなものがあります。
C#Select
OrderBy
FirstOrDefault
Any
Count
ToList
たとえば、20歳以上のユーザーの名前だけを取得したい場合は、WhereとSelectを組み合わせます。
C#var names = users
.Where(user => user.Age >= 20)
.Select(user => user.Name);
7-1. Selectで絞り込んだ結果を変換する
Selectは、要素を別の形に変換するためのメソッドです。
Whereで絞り込んだ後、必要なプロパティだけを取り出すときによく使います。
C#var adultNames = users
.Where(user => user.Age >= 20)
.Select(user => user.Name);
このコードは、20歳以上のユーザーを絞り込み、その名前だけを取り出します。
結果を表示する例です。
C#foreach (var name in adultNames)
{
Console.WriteLine(name);
}
匿名型に変換することもできます。
C#var result = users
.Where(user => user.Age >= 20)
.Select(user => new
{
user.Name,
user.Age
});
Whereは絞り込み、Selectは変換と覚えると分かりやすいです。
7-2. OrderByで絞り込んだ結果を並び替える
OrderByは、要素を昇順に並び替えるためのメソッドです。
C#var result = users
.Where(user => user.Age >= 20)
.OrderBy(user => user.Age);
このコードは、20歳以上のユーザーを年齢の昇順に並び替えます。
降順にしたい場合は、OrderByDescendingを使います。
C#var result = users
.Where(user => user.Age >= 20)
.OrderByDescending(user => user.Age);
商品価格で並び替える例です。
C#var result = products
.Where(product => product.Stock > 0)
.OrderBy(product => product.Price);
このコードは、在庫がある商品だけを取り出し、価格の安い順に並び替えます。
7-3. FirstOrDefaultで条件に合う最初の要素を取得する
Whereは条件に合う要素の集まりを返します。
一方、条件に合う最初の1件だけが欲しい場合は、FirstOrDefaultを使います。
C#var user = users.FirstOrDefault(user => user.Id == 1);
Whereと組み合わせて書くこともできます。
C#var user = users
.Where(user => user.Age >= 20)
.FirstOrDefault();
ただし、条件が1つだけなら、次のようにFirstOrDefaultに直接条件を書く方が簡潔です。
C#var user = users.FirstOrDefault(user => user.Age >= 20);
Whereは複数件の絞り込み、FirstOrDefaultは最初の1件の取得と覚えましょう。
7-4. Anyで条件に合う要素が存在するか判定する
Anyは、条件に合う要素が1つでも存在するかどうかを判定するメソッドです。
C#bool exists = users.Any(user => user.Age >= 20);
このコードは、20歳以上のユーザーが1人でもいればtrueを返します。
WhereとAnyを組み合わせることもできます。
C#bool exists = users
.Where(user => user.IsActive)
.Any(user => user.Age >= 20);
ただし、単純な条件なら次のように書いた方が読みやすいです。
C#bool exists = users.Any(user => user.IsActive && user.Age >= 20);
存在チェックだけが目的なら、Where(...).Count() > 0よりもAnyを使うのが一般的です。
C#// あまりおすすめしない
bool exists = users.Where(user => user.Age >= 20).Count() > 0;
// おすすめ
bool exists = users.Any(user => user.Age >= 20);
7-5. Countで条件に合う要素数を数える
Countは、要素数を数えるためのメソッドです。
Whereで絞り込んだ後に数えることができます。
C#int count = users
.Where(user => user.Age >= 20)
.Count();
ただし、Countには条件を直接書けます。
C#int count = users.Count(user => user.Age >= 20);
このコードは、20歳以上のユーザー数を数えます。
商品一覧から在庫ありの商品数を数える例です。
C#int availableCount = products.Count(product => product.Stock > 0);
件数が欲しいだけなら、Where(...).Count()よりもCount(条件)の方が簡潔です。
8. Whereメソッドの注意点
Whereメソッドは便利ですが、初心者が誤解しやすいポイントもあります。
特に重要なのは次の5つです。
C#Whereは元のコレクションを変更しない
Whereの戻り値は単一の要素ではない
条件に合う要素がない場合は空の結果になる
Whereは遅延実行される
ToListを呼ぶタイミングに注意する
これらを理解しておくと、LINQの挙動で迷いにくくなります。
8-1. Whereは元のコレクションを変更しない
Whereは、元のコレクションを変更しません。
次のコードを見てください。
C#var numbers = new List<int> { 1, 2, 3, 4, 5 };
var result = numbers.Where(n => n >= 3);
foreach (var number in numbers)
{
Console.WriteLine(number);
}
実行結果は次のとおりです。
C#1
2
3
4
5
Whereを使っても、元のnumbers自体は変わりません。
絞り込んだ結果を使いたい場合は、resultを使います。
C#foreach (var number in result)
{
Console.WriteLine(number);
}
元のリストを絞り込んだ結果で置き換えたい場合は、次のように書きます。
C#numbers = numbers.Where(n => n >= 3).ToList();
8-2. Whereの戻り値は単一の要素ではなくコレクション
Whereの戻り値は、条件に合った要素の集まりです。
C#var result = users.Where(user => user.Id == 1);
このコードでは、Idが1のユーザーが1人だけだったとしても、resultはユーザー1件ではなくコレクションです。
そのため、次のように1件のユーザーとして扱うことはできません。
C#// エラーになる考え方
Console.WriteLine(result.Name);
1件だけ取得したい場合は、FirstOrDefaultを使います。
C#var user = users.FirstOrDefault(user => user.Id == 1);
if (user != null)
{
Console.WriteLine(user.Name);
}
複数件を処理したい場合は、foreachを使います。
C#foreach (var user in result)
{
Console.WriteLine(user.Name);
}
8-3. 条件に合う要素がない場合の結果
Whereで条件に合う要素がない場合、結果は空のコレクションになります。
C#var numbers = new List<int> { 1, 2, 3 };
var result = numbers.Where(n => n >= 10);
この場合、resultには要素がありません。
ただし、result自体がnullになるわけではありません。
C#foreach (var number in result)
{
Console.WriteLine(number);
}
このforeachは何も表示せずに終了します。
件数を確認したい場合は、AnyやCountを使います。
C#if (!result.Any())
{
Console.WriteLine("条件に合うデータはありません。");
}
または次のように書けます。
C#int count = result.Count();
Console.WriteLine(count);
8-4. 遅延実行とは
Whereは遅延実行されます。
遅延実行とは、Whereを書いた時点ではまだ処理が実行されず、実際に結果を取り出すタイミングで処理される仕組みです。
次のコードを見てください。
C#var numbers = new List<int> { 1, 2, 3 };
var result = numbers.Where(n => n >= 2);
numbers.Add(4);
foreach (var number in result)
{
Console.WriteLine(number);
}
実行結果は次のようになります。
C#2
3
4
Whereを書いた後にnumbers.Add(4)をしていますが、結果には4も含まれています。
これは、foreachで取り出すタイミングでWhereの条件が評価されるためです。
8-5. ToListを呼ぶタイミングに注意する
遅延実行を避けて、その時点の結果を確定させたい場合は、ToListを使います。
C#var numbers = new List<int> { 1, 2, 3 };
var result = numbers.Where(n => n >= 2).ToList();
numbers.Add(4);
foreach (var number in result)
{
Console.WriteLine(number);
}
実行結果は次のとおりです。
C#2
3
ToListを呼んだ時点で結果が確定するため、その後に元のリストへ追加した4は含まれません。
ただし、何でもすぐにToListすればよいわけではありません。
不要なタイミングでToListを呼ぶと、メモリ使用量が増えたり、処理が早く実行されすぎたりすることがあります。
必要な場面でだけToListを使いましょう。
9. IEnumerableとIQueryableにおけるWhereの違い
Whereは、IEnumerable<T>とIQueryable<T>のどちらにも使えます。
ただし、内部の動きは異なります。
簡単にいうと、IEnumerable<T>のWhereはC#のメモリ上で処理されることが多く、IQueryable<T>のWhereはデータベースなど外部のデータソースに対する問い合わせとして処理されることが多いです。
9-1. IEnumerableで使うWhere
IEnumerable<T>は、配列やListなどのコレクションでよく使われます。
C#IEnumerable<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var result = numbers.Where(n => n >= 3);
この場合、Whereの処理はC#側で行われます。
たとえば、リストの中身を1つずつ見て、条件に合うものだけを返します。
C#foreach (var number in result)
{
Console.WriteLine(number);
}
IEnumerable<T>は、すでにメモリ上にあるデータを処理する場合によく使います。
9-2. IQueryableで使うWhere
IQueryable<T>は、Entity Frameworkなどでデータベースに問い合わせるときによく使われます。
C#IQueryable<User> query = dbContext.Users;
var result = query.Where(user => user.Age >= 20);
この場合、Whereの条件はすぐにC#側で実行されるとは限りません。
多くの場合、SQLに変換されてデータベース側で実行されます。
SQLWHERE Age >= 20
つまり、IQueryable<T>のWhereは、データベースに送る問い合わせを組み立てているイメージです。
実際にデータを取得するのは、ToListやFirstOrDefaultなどを呼んだタイミングです。
C#var users = dbContext.Users
.Where(user => user.Age >= 20)
.ToList();
9-3. Entity FrameworkでWhereを使うときの注意点
Entity FrameworkでWhereを使う場合は、C#のすべての処理がSQLに変換できるわけではない点に注意が必要です。
たとえば、単純な比較は多くの場合問題ありません。
C#var result = dbContext.Users
.Where(user => user.Age >= 20)
.ToList();
文字列のContainsも、データベース側で検索条件に変換されることがあります。
C#var result = dbContext.Users
.Where(user => user.Name.Contains("田中"))
.ToList();
一方、自作メソッドをWhereの中で使うと、SQLに変換できずエラーになる場合があります。
C#var result = dbContext.Users
.Where(user => IsTargetUser(user))
.ToList();
Entity Frameworkでデータベース検索をする場合は、できるだけSQLに変換しやすい条件を書くことが大切です。
C#var result = dbContext.Users
.Where(user => user.Age >= 20 && user.IsActive)
.ToList();
9-4. DBアクセス時に意識したいパフォーマンス
データベースを使う場合、Whereをどこで使うかはパフォーマンスに大きく関わります。
悪い例です。
C#var users = dbContext.Users.ToList();
var adults = users.Where(user => user.Age >= 20);
このコードでは、まず全ユーザーをデータベースから取得し、その後C#側で絞り込んでいます。
データ件数が多い場合、無駄なデータを大量に取得してしまいます。
よい例です。
C#var adults = dbContext.Users
.Where(user => user.Age >= 20)
.ToList();
このように、ToListの前にWhereを書くと、条件に合うデータだけをデータベースから取得できます。
データベースアクセスでは、できるだけ早い段階でWhereによる絞り込みを行うのが基本です。
10. Whereメソッドでよくあるエラーと対処法
Whereメソッドは便利ですが、初心者がよく遭遇するエラーがあります。
代表的なものは次のとおりです。
C#System.Linqのusingがない
条件式がboolを返していない
null参照でエラーになる
ToListし忘れて期待通りの結果にならない
WhereとFirstOrDefaultを混同している
それぞれの原因と対処法を見ていきましょう。
10-1. System.Linqのusingがない
Whereが使えない場合、まず確認したいのがusing System.Linq;です。
C#using System.Linq;
これがないと、環境によっては次のようなコードでエラーになることがあります。
C#var result = numbers.Where(n => n > 10);
エラー内容としては、「Whereの定義が見つからない」といった意味のメッセージが表示されます。
対処法は、ファイルの先頭に次の行を追加することです。
C#using System.Linq;
また、対象がLINQを使える型になっているかも確認しましょう。
配列やList<T>であれば通常は問題なく使えます。
10-2. 条件式がboolを返していない
Whereの条件式は、必ずboolを返す必要があります。
間違った例です。
C#var result = numbers.Where(n => n + 1);
n + 1は数値を返しており、boolではありません。
正しい例です。
C#var result = numbers.Where(n => n + 1 > 10);
この場合、n + 1 > 10はtrueまたはfalseを返すため、Whereの条件として使えます。
文字列の場合も同じです。
C#// 正しい例
var result = names.Where(name => name.Contains("a"));
Containsは、指定した文字を含むかどうかをboolで返します。
10-3. null参照でエラーになる
Whereの条件式の中で、nullの可能性がある値にアクセスするとエラーになることがあります。
たとえば、次のコードです。
C#var result = users.Where(user => user.Name.Contains("田中"));
もしuser.Nameがnullの場合、Containsを呼び出せずにエラーになります。
対処法としては、nullチェックを入れます。
C#var result = users.Where(user =>
user.Name != null && user.Name.Contains("田中"));
または、null条件演算子を使う方法もあります。
C#var result = users.Where(user =>
user.Name?.Contains("田中") == true);
空文字も除外したい場合は、次のように書けます。
C#var result = users.Where(user =>
!string.IsNullOrEmpty(user.Name) &&
user.Name.Contains("田中"));
nullの可能性があるプロパティを条件に使うときは、必ずnull対策を意識しましょう。
10-4. ToListし忘れて期待通りの結果にならない
Whereは遅延実行されるため、ToListし忘れると期待と違う結果になることがあります。
C#var numbers = new List<int> { 1, 2, 3 };
var result = numbers.Where(n => n >= 2);
numbers.Add(4);
このあとresultを列挙すると、4も含まれます。
C#foreach (var number in result)
{
Console.WriteLine(number);
}
実行結果は次のようになります。
C#2
3
4
Whereを書いた時点の結果を確定したい場合は、ToListを使います。
C#var result = numbers.Where(n => n >= 2).ToList();
numbers.Add(4);
この場合、resultには2と3だけが入ります。
遅延実行を理解すると、LINQの挙動を正しく予測できるようになります。
10-5. WhereとFirstOrDefaultを混同している
WhereとFirstOrDefaultの混同もよくあります。
Whereは条件に合う要素の集まりを返します。
C#var result = users.Where(user => user.Id == 1);
FirstOrDefaultは条件に合う最初の1件を返します。
C#var user = users.FirstOrDefault(user => user.Id == 1);
1件だけ欲しいのにWhereを使うと、結果がコレクションになってしまいます。
C#var user = users.Where(user => user.Id == 1);
// user.Name のようには扱えない
1件だけ欲しい場合は、次のように書きましょう。
C#var user = users.FirstOrDefault(user => user.Id == 1);
if (user != null)
{
Console.WriteLine(user.Name);
}
複数件を処理したい場合はWhere、1件だけ取得したい場合はFirstOrDefaultと使い分けるのが基本です。
11. 実践で使えるWhereメソッドのサンプルコード集
ここからは、実践でよく使うWhereメソッドのサンプルコードを紹介します。
実務では、年齢、価格、名前、nullチェック、日付などを条件にしてデータを絞り込む場面がよくあります。
基本パターンを覚えておくと、さまざまな場面で応用できます。
11-1. 年齢でユーザーを絞り込む
ユーザー一覧から20歳以上のユーザーだけを取り出す例です。
C#using System;
using System.Collections.Generic;
using System.Linq;
class User
{
public string Name { get; set; } = "";
public int Age { get; set; }
}
class Program
{
static void Main()
{
var users = new List<User>
{
new User { Name = "太郎", Age = 18 },
new User { Name = "花子", Age = 25 },
new User { Name = "健一", Age = 32 }
};
var adults = users.Where(user => user.Age >= 20);
foreach (var user in adults)
{
Console.WriteLine($"{user.Name}さんは成人です。");
}
}
}
実行結果です。
C#花子さんは成人です。
健一さんは成人です。
年齢のような数値条件では、>=、<=、>、<をよく使います。
11-2. 商品価格で商品一覧を絞り込む
商品一覧から、指定価格以下の商品を取り出す例です。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Product
{
public string Name { get; set; } = "";
public int Price { get; set; }
}
class Program
{
static void Main()
{
var products = new List<Product>
{
new Product { Name = "キーボード", Price = 3000 },
new Product { Name = "マウス", Price = 1500 },
new Product { Name = "モニター", Price = 25000 }
};
var cheapProducts = products.Where(product => product.Price <= 5000);
foreach (var product in cheapProducts)
{
Console.WriteLine($"{product.Name}: {product.Price}円");
}
}
}
実行結果です。
C#キーボード: 3000円
マウス: 1500円
価格条件では、在庫やセール状態と組み合わせることも多いです。
C#var result = products.Where(product =>
product.Price <= 5000 &&
product.Stock > 0);
11-3. 名前に特定の文字を含むデータを絞り込む
文字列に特定の文字を含むかどうかを判定するには、Containsを使います。
C#var users = new List<User>
{
new User { Name = "田中太郎", Age = 20 },
new User { Name = "佐藤花子", Age = 25 },
new User { Name = "田村健一", Age = 30 }
};
var result = users.Where(user => user.Name.Contains("田"));
foreach (var user in result)
{
Console.WriteLine(user.Name);
}
実行結果です。
C#田中太郎
田村健一
前方一致ならStartsWithを使います。
C#var result = users.Where(user => user.Name.StartsWith("田"));
後方一致ならEndsWithを使います。
C#var result = users.Where(user => user.Name.EndsWith("子"));
検索機能を作るときによく使うパターンです。
11-4. nullや空文字を除外する
文字列リストから、nullや空文字を除外する例です。
C#var names = new List<string?>
{
"太郎",
"",
null,
"花子",
" ",
"健一"
};
var result = names.Where(name => !string.IsNullOrWhiteSpace(name));
foreach (var name in result)
{
Console.WriteLine(name);
}
実行結果です。
C#太郎
花子
健一
string.IsNullOrEmptyは、nullまたは空文字を判定します。
C#string.IsNullOrEmpty(name)
string.IsNullOrWhiteSpaceは、null、空文字、空白だけの文字列を判定します。
C#string.IsNullOrWhiteSpace(name)
空白だけの文字列も除外したい場合は、IsNullOrWhiteSpaceを使うのがおすすめです。
11-5. 日付条件でデータを絞り込む
日付条件でデータを絞り込む例です。
次の例では、今日以降の予定だけを取り出します。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Schedule
{
public string Title { get; set; } = "";
public DateTime Date { get; set; }
}
class Program
{
static void Main()
{
var schedules = new List<Schedule>
{
new Schedule { Title = "過去の予定", Date = DateTime.Today.AddDays(-1) },
new Schedule { Title = "今日の予定", Date = DateTime.Today },
new Schedule { Title = "明日の予定", Date = DateTime.Today.AddDays(1) }
};
var upcomingSchedules = schedules.Where(schedule =>
schedule.Date >= DateTime.Today);
foreach (var schedule in upcomingSchedules)
{
Console.WriteLine($"{schedule.Date:yyyy/MM/dd}: {schedule.Title}");
}
}
}
実行結果の例です。
C#2026/06/12: 今日の予定
2026/06/13: 明日の予定
日付範囲で絞り込む場合は、AND条件を使います。
C#var startDate = new DateTime(2026, 6, 1);
var endDate = new DateTime(2026, 6, 30);
var result = schedules.Where(schedule =>
schedule.Date >= startDate &&
schedule.Date <= endDate);
このコードは、2026年6月1日から2026年6月30日までの予定を取り出します。
12. C#のwhereを理解するためのよくある質問
最後に、C#のwhereやLINQのWhereメソッドについて、初心者が疑問に思いやすい点を解説します。
Whereは便利なメソッドですが、if文、Find、FirstOrDefaultなどと役割が似ている部分もあるため、最初は混乱しやすいです。
それぞれの違いを整理しておきましょう。
12-1. Whereとif文は何が違う?
Whereとif文は、どちらも条件を扱います。
ただし、役割が違います。
if文は、条件によって処理を分岐するために使います。
C#if (age >= 20)
{
Console.WriteLine("成人です");
}
Whereは、コレクションから条件に合う要素だけを取り出すために使います。
C#var adults = users.Where(user => user.Age >= 20);
if文でも絞り込みはできます。
C#var adults = new List<User>();
foreach (var user in users)
{
if (user.Age >= 20)
{
adults.Add(user);
}
}
これをLINQで短く書くと、次のようになります。
C#var adults = users.Where(user => user.Age >= 20).ToList();
条件分岐にはif文、コレクションの絞り込みにはWhereを使うと考えると分かりやすいです。
12-2. WhereとFindの違いは?
Findは、List<T>で使えるメソッドです。
条件に合う最初の1件を返します。
C#var user = users.Find(user => user.Id == 1);
一方、Whereは条件に合うすべての要素を返します。
C#var users = users.Where(user => user.Age >= 20);
つまり、違いは次のとおりです。
C#Find // 条件に合う最初の1件を取得する
Where // 条件に合うすべての要素を取得する
また、Findは主にList<T>のメソッドですが、WhereはLINQのメソッドなので、配列やさまざまなコレクションで使いやすいです。
1件だけ欲しい場合はFindまたはFirstOrDefault、複数件欲しい場合はWhereを使いましょう。
12-3. WhereとFirstOrDefaultの違いは?
Whereは、条件に合う要素の集まりを返します。
C#var result = users.Where(user => user.Age >= 20);
FirstOrDefaultは、条件に合う最初の1件を返します。
C#var user = users.FirstOrDefault(user => user.Age >= 20);
戻り値のイメージは次のとおりです。
C#Where // 複数件の可能性がある
FirstOrDefault // 1件またはnull
条件に合うユーザーを一覧表示したいならWhereです。
C#foreach (var user in users.Where(user => user.Age >= 20))
{
Console.WriteLine(user.Name);
}
条件に合うユーザーを1人だけ取得したいならFirstOrDefaultです。
C#var user = users.FirstOrDefault(user => user.Age >= 20);
if (user != null)
{
Console.WriteLine(user.Name);
}
12-4. Whereは何回でもつなげられる?
Whereは複数回つなげられます。
C#var result = users
.Where(user => user.Age >= 20)
.Where(user => user.IsActive)
.Where(user => !user.IsDeleted);
このコードは、次のように1つのWhereにまとめることもできます。
C#var result = users.Where(user =>
user.Age >= 20 &&
user.IsActive &&
!user.IsDeleted);
どちらの書き方でも問題ありません。
条件ごとに意味を分けて読みやすくしたい場合は、複数のWhereを使うとよいです。
C#var result = users
.Where(user => user.Age >= 20) // 年齢条件
.Where(user => user.IsActive) // 有効ユーザー
.Where(user => !user.IsDeleted); // 未削除
ただし、条件が短い場合は1つにまとめた方がすっきりすることもあります。
12-5. Whereを使うと処理は重くなる?
Whereを使ったからといって、必ず処理が重くなるわけではありません。
むしろ、手書きのforeachと比べても、可読性が高くなるメリットがあります。
C#var result = users.Where(user => user.Age >= 20);
ただし、使い方によってはパフォーマンスに影響することがあります。
たとえば、データベースから全件取得した後にWhereで絞り込むのは非効率です。
C#var users = dbContext.Users.ToList();
var adults = users.Where(user => user.Age >= 20);
この場合、全ユーザーを取得してからC#側で絞り込んでいます。
効率を考えるなら、ToListの前にWhereを書きます。
C#var adults = dbContext.Users
.Where(user => user.Age >= 20)
.ToList();
また、同じWhereの結果を何度も使う場合は、必要に応じてToListで結果を確定させるとよいです。
C#var adults = users
.Where(user => user.Age >= 20)
.ToList();
通常のアプリケーション開発では、まず読みやすく正しいコードを書くことを優先し、処理が遅いと分かった部分を必要に応じて改善するのがおすすめです。
まとめ
C#のwhereには複数の使い方がありますが、初心者がまず覚えるべきなのはLINQのWhereメソッドです。
Whereメソッドは、配列やListなどのコレクションから、条件に合う要素だけを取り出すために使います。
基本構文は次のとおりです。
C#var result = collection.Where(item => 条件式);
たとえば、20歳以上のユーザーだけを取り出す場合は、次のように書きます。
C#var adults = users.Where(user => user.Age >= 20);
Whereを使うと、foreachとif文で書いていた絞り込み処理を、短く分かりやすく書けます。
C#var adults = users
.Where(user => user.Age >= 20)
.ToList();
重要なポイントは次のとおりです。
Whereの条件式にはboolを返す処理を書きます。
C#user => user.Age >= 20
Whereの戻り値は単一の要素ではなく、条件に合う要素の集まりです。
C#var result = users.Where(user => user.Age >= 20);
1件だけ欲しい場合は、FirstOrDefaultを使います。
C#var user = users.FirstOrDefault(user => user.Id == 1);
Whereは元のコレクションを変更しません。
C#var result = numbers.Where(n => n >= 3);
元のリストを絞り込んだ結果に置き換えたい場合は、次のように書きます。
C#numbers = numbers.Where(n => n >= 3).ToList();
また、Whereは遅延実行されるため、結果をその時点で確定したい場合はToListやToArrayを使います。
C#var result = numbers.Where(n => n >= 3).ToList();
C#のWhereは、LINQを使いこなすうえで必須のメソッドです。
数値、文字列、オブジェクト、日付、nullチェックなど、さまざまな条件でデータを絞り込めます。
まずは次のようなシンプルなコードから練習してみましょう。
C#var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
foreach (var number in evenNumbers)
{
Console.WriteLine(number);
}
Whereの基本を理解できると、Select、OrderBy、Any、Count、FirstOrDefaultなど、ほかのLINQメソッドも理解しやすくなります。

