C# Containsの使い方を完全解説|文字列・List検索・大文字小文字の注意点まで
はじめに
C#で「文字列に特定の単語が含まれているか」「Listの中に指定した値が存在するか」を調べたいときによく使うのがContainsです。
Containsは、C#の実務でも非常に使用頻度の高いメソッドです。たとえば、ユーザーが入力した文字列に禁止ワードが含まれていないか確認したり、商品IDの一覧に指定したIDがあるか調べたり、検索キーワードでデータを絞り込んだりするときに使います。
一方で、Containsにはいくつか注意点もあります。特に、文字列検索では大文字小文字の扱い、nullの扱い、Listや配列で使う場合の違い、独自クラスを検索するときの比較方法などを理解していないと、「思ったとおりにtrueにならない」「エラーになる」といった問題が起こります。
この記事では、C#のContainsの基本から、文字列・List・配列・LINQでの使い方、大文字小文字を無視する方法、よくあるエラー、パフォーマンス面の注意点まで、初心者にもわかりやすく解説します。
1. C#のContainsとは?できることを最初に理解しよう
1-1. Containsは「含まれているか」をboolで判定するメソッド
C#のContainsは、対象の中に指定した値が含まれているかどうかを調べるメソッドです。結果はbool型で返されます。
つまり、含まれていればtrue、含まれていなければfalseになります。
C#string text = "Hello C#";
bool result = text.Contains("C#");
Console.WriteLine(result); // True
この例では、文字列"Hello C#"の中に"C#"が含まれているため、trueが返されます。
Containsは「あるかないか」を判定したいときに便利です。位置を知りたい場合はIndexOf、条件を指定して探したい場合はAnyなど、目的によって使い分けることも重要です。
1-2. 文字列・List・配列・LINQで使われるContainsの違い
C#のContainsは、さまざまな場面で使われます。ただし、対象によって意味や使い方が少し異なります。
文字列のContainsは、文字列の中に指定した文字列や文字が含まれているかを調べます。
C#string message = "C#を学習中です";
bool result = message.Contains("C#");
List.Containsは、Listの中に指定した要素が存在するかを調べます。
C#List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
bool result = names.Contains("Bob");
配列でContainsを使う場合は、LINQの拡張メソッドとして使うのが一般的です。
C#using System.Linq;
int[] numbers = { 1, 2, 3, 4, 5 };
bool result = numbers.Contains(3);
このように、同じContainsでも、文字列に対して使うのか、コレクションに対して使うのかで意味が変わります。
1-3. Containsがtrue/falseを返す基本的な仕組み
Containsは、指定した値が対象の中に見つかるかどうかを判定します。
文字列の場合は、対象文字列の中に検索文字列が部分的に含まれているかを調べます。
C#string text = "apple banana orange";
Console.WriteLine(text.Contains("banana")); // True
Console.WriteLine(text.Contains("grape")); // False
Listの場合は、List内の要素と指定した値を比較し、一致する要素があればtrueを返します。
C#List<int> numbers = new List<int> { 10, 20, 30 };
Console.WriteLine(numbers.Contains(20)); // True
Console.WriteLine(numbers.Contains(40)); // False
重要なのは、Containsは「何らかの値が存在するか」を調べるメソッドであり、検索結果そのものを取得するメソッドではないという点です。
たとえば、該当する要素を取得したい場合はFirstOrDefault、条件で絞り込みたい場合はWhere、存在チェックだけでよい場合はContainsやAnyを使うとよいでしょう。
2. 文字列でContainsを使う方法
2-1. string.Containsの基本構文
文字列に対してContainsを使う基本構文は次のとおりです。
C#文字列.Contains(検索したい文字列)
実際のコードでは次のように書きます。
C#string text = "C# Containsの使い方";
bool result = text.Contains("Contains");
Console.WriteLine(result); // True
Containsの戻り値はboolなので、if文と組み合わせて使うことが多いです。
C#string text = "C#を勉強しています";
if (text.Contains("C#"))
{
Console.WriteLine("C#に関する文章です");
}
else
{
Console.WriteLine("C#は含まれていません");
}
このように、string.Containsを使うと、文字列の中に特定のキーワードが含まれているかを簡単に判定できます。
2-2. 指定した文字や単語を含むか判定するサンプル
指定した単語が含まれているかを判定する例を見てみましょう。
C#string sentence = "私はC#でWebアプリを開発しています";
bool hasCSharp = sentence.Contains("C#");
Console.WriteLine(hasCSharp); // True
指定した1文字が含まれているかを調べることもできます。
C#string code = "ABC123";
bool hasA = code.Contains("A");
Console.WriteLine(hasA); // True
C#では、環境やバージョンによってはcharを指定できるオーバーロードも利用できます。
C#string code = "ABC123";
bool hasA = code.Contains('A');
Console.WriteLine(hasA); // True
ただし、初心者のうちは文字列として"A"のように書いても問題ありません。検索したい対象が文字列なのか1文字なのかを意識して使うとよいでしょう。
2-3. 日本語・英数字・記号を含む文字列検索の例
Containsは、日本語の文字列にも使用できます。
C#string text = "東京都渋谷区に住んでいます";
bool result = text.Contains("渋谷");
Console.WriteLine(result); // True
英数字を含む文字列でも同じように使えます。
C#string productCode = "ITEM-2026-A001";
Console.WriteLine(productCode.Contains("2026")); // True
Console.WriteLine(productCode.Contains("B001")); // False
記号を含む検索も可能です。
C#string email = "sample@example.com";
Console.WriteLine(email.Contains("@")); // True
Console.WriteLine(email.Contains(".com")); // True
たとえば、メールアドレスらしき文字列かどうかを簡易的にチェックしたい場合、@が含まれているかをContainsで判定できます。
C#string input = "user@example.com";
if (input.Contains("@"))
{
Console.WriteLine("メールアドレスの可能性があります");
}
ただし、Contains("@")だけでは正しいメールアドレスかどうかまでは判定できません。厳密な形式チェックには正規表現や専用のバリデーション処理を使う必要があります。
2-4. Containsで部分一致検索を行うときの注意点
string.Containsは部分一致検索です。つまり、完全に同じ文字列でなくても、対象文字列の一部に含まれていればtrueになります。
C#string text = "JavaScript";
Console.WriteLine(text.Contains("Java")); // True
この例では、"JavaScript"の中に"Java"が含まれているためtrueになります。
これは便利ですが、意図しない一致を生む場合もあります。
C#string text = "cat catalog category";
Console.WriteLine(text.Contains("cat")); // True
"cat"を検索すると、"cat"単体だけでなく、"catalog"や"category"にも一致します。
単語として完全一致させたい場合は、単純なContainsだけでは不十分です。スペースで分割して比較したり、正規表現を使ったりする必要があります。
C#string text = "cat catalog category";
string[] words = text.Split(' ');
bool result = words.Contains("cat");
Console.WriteLine(result); // True
このように、部分一致でよいのか、単語単位で一致させたいのか、完全一致させたいのかを考えて使うことが大切です。
3. Listや配列でContainsを使う方法
3-1. List.Containsの基本構文
List<T>に対してContainsを使う基本構文は次のとおりです。
C#list.Contains(探したい値)
たとえば、文字列のListに特定の名前が含まれているかを調べる場合は、次のように書きます。
C#List<string> users = new List<string> { "Tanaka", "Suzuki", "Sato" };
bool exists = users.Contains("Suzuki");
Console.WriteLine(exists); // True
List.Containsも戻り値はboolです。そのため、if文で存在チェックをする場面でよく使われます。
C#List<string> roles = new List<string> { "Admin", "User", "Guest" };
if (roles.Contains("Admin"))
{
Console.WriteLine("管理者権限があります");
}
3-2. List内に特定の値が存在するか調べる方法
数値のListでもContainsは使えます。
C#List<int> ids = new List<int> { 101, 102, 103, 104 };
bool hasId = ids.Contains(103);
Console.WriteLine(hasId); // True
文字列のListでも同じです。
C#List<string> categories = new List<string>
{
"Books",
"Games",
"Music"
};
Console.WriteLine(categories.Contains("Games")); // True
Console.WriteLine(categories.Contains("Food")); // False
List.Containsは、指定した値とList内の要素を比較して、一致するものがあるかを調べます。
ただし、文字列の場合は大文字小文字が区別されます。
C#List<string> names = new List<string> { "Alice", "Bob" };
Console.WriteLine(names.Contains("Alice")); // True
Console.WriteLine(names.Contains("alice")); // False
大文字小文字を無視してList内を検索したい場合は、AnyとStringComparisonを組み合わせる方法が便利です。
C#List<string> names = new List<string> { "Alice", "Bob" };
bool result = names.Any(name =>
name.Equals("alice", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(result); // True
3-3. 配列でContainsを使うにはLINQが必要
配列に対してContainsを使う場合は、LINQの拡張メソッドを使います。そのため、ファイルの先頭にusing System.Linq;が必要です。
C#using System.Linq;
int[] numbers = { 1, 2, 3, 4, 5 };
bool result = numbers.Contains(3);
Console.WriteLine(result); // True
文字列配列でも同様です。
C#using System.Linq;
string[] fruits = { "Apple", "Banana", "Orange" };
bool result = fruits.Contains("Banana");
Console.WriteLine(result); // True
using System.Linq;がないと、環境によってはContainsが見つからず、コンパイルエラーになることがあります。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] colors = { "Red", "Green", "Blue" };
if (colors.Contains("Green"))
{
Console.WriteLine("Greenが含まれています");
}
}
}
近年のプロジェクトテンプレートでは暗黙的なusingが有効になっている場合もありますが、エラーが出る場合はusing System.Linq;を確認しましょう。
3-4. int・string・object型でのContainsの使い方の違い
Containsは、Listや配列の要素の型によって比較のされ方が変わります。
intなどの値型では、値そのものが一致するかを比較します。
C#List<int> numbers = new List<int> { 1, 2, 3 };
Console.WriteLine(numbers.Contains(2)); // True
stringでは、文字列の内容が一致するかを比較します。
C#List<string> names = new List<string> { "Alice", "Bob" };
Console.WriteLine(names.Contains("Bob")); // True
一方で、独自クラスやobject型を扱う場合は注意が必要です。
C#class User
{
public int Id { get; set; }
public string Name { get; set; }
}
次のように同じ値を持つオブジェクトを検索しても、期待どおりtrueにならない場合があります。
C#List<User> users = new List<User>
{
new User { Id = 1, Name = "Alice" }
};
User target = new User { Id = 1, Name = "Alice" };
Console.WriteLine(users.Contains(target)); // Falseになる場合がある
これは、既定ではオブジェクトの中身ではなく、同じインスタンスかどうかで比較されるためです。独自クラスで値の一致を判定したい場合は、Equalsをオーバーライドするか、Anyで条件を指定する方法がよく使われます。
C#bool result = users.Any(user => user.Id == target.Id);
Console.WriteLine(result); // True
4. Containsの大文字小文字の注意点
4-1. string.Containsは基本的に大文字小文字を区別する
string.Containsを使うときに特に注意したいのが、大文字小文字の扱いです。
通常、Containsは大文字小文字を区別します。
C#string text = "Hello C#";
Console.WriteLine(text.Contains("Hello")); // True
Console.WriteLine(text.Contains("hello")); // False
"Hello"と"hello"は、人間にとっては同じ単語のように見えるかもしれませんが、C#の文字列比較では別の文字列として扱われます。
検索機能やログインIDのチェック、入力キーワードの判定などでは、大文字小文字を区別したい場合と、区別したくない場合があります。どちらの動作が必要なのかを明確にして実装しましょう。
4-2. 大文字小文字を無視して検索する方法
大文字小文字を無視して検索したい場合、主に次の方法があります。
1つ目は、StringComparison.OrdinalIgnoreCaseを指定する方法です。
C#string text = "Hello C#";
bool result = text.Contains("hello", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(result); // True
2つ目は、検索対象と検索キーワードの両方を小文字または大文字に変換して比較する方法です。
C#string text = "Hello C#";
bool result = text.ToLower().Contains("hello".ToLower());
Console.WriteLine(result); // True
ただし、現在のC#では、可能であればStringComparison.OrdinalIgnoreCaseを使う方法がおすすめです。比較方法の意図が明確で、余計な文字列変換を避けやすいためです。
4-3. StringComparison.OrdinalIgnoreCaseを使う方法
StringComparison.OrdinalIgnoreCaseを使うと、大文字小文字を無視した比較ができます。
C#string text = "C# Contains Sample";
bool result = text.Contains("contains", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(result); // True
実務では、ユーザー入力による検索機能などでよく使います。
C#string title = "C# Containsの使い方";
string keyword = "contains";
if (title.Contains(keyword, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("キーワードが見つかりました");
}
OrdinalIgnoreCaseは、文化圏に依存しない比較を大文字小文字を無視して行う指定です。プログラム内部のID、コード、英数字のキーワード検索などでは扱いやすい選択肢です。
一方で、言語や文化に依存する自然言語の比較を厳密に扱う場合は、要件に応じて別のStringComparisonを検討することもあります。
4-4. ToLower・ToUpperで比較する方法と注意点
大文字小文字を無視する方法として、ToLowerやToUpperを使う書き方もあります。
C#string text = "Hello C#";
string keyword = "hello";
bool result = text.ToLower().Contains(keyword.ToLower());
Console.WriteLine(result); // True
この方法は直感的でわかりやすいですが、注意点もあります。
まず、ToLowerやToUpperは新しい文字列を作るため、検索対象が多い場合やループ内で大量に実行する場合は無駄が増えることがあります。
また、カルチャによって大文字小文字変換の結果が変わる可能性もあります。英数字中心の単純な比較であれば大きな問題になりにくいですが、明確な比較方法を指定できるStringComparison.OrdinalIgnoreCaseのほうが意図を伝えやすいです。
避けたい例は次のような書き方です。
C#if (text.ToLower().Contains(keyword.ToLower()))
{
// 大量データでは無駄な変換が増える可能性がある
}
おすすめは次の書き方です。
C#if (text.Contains(keyword, StringComparison.OrdinalIgnoreCase))
{
// 比較方法が明確
}
ただし、使用している.NETのバージョンによってはContainsにStringComparisonを指定できない場合があります。その場合は、IndexOfを使う方法もあります。
C#bool result = text.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0;
5. Containsでよくあるエラーと対処法
5-1. nullの文字列にContainsを使うと例外になる
Containsでよくあるエラーの1つが、nullの文字列に対してContainsを呼び出してしまうケースです。
C#string text = null;
bool result = text.Contains("C#"); // NullReferenceException
このコードは、textがnullのためNullReferenceExceptionになります。
対処法としては、nullチェックをしてからContainsを呼び出します。
C#string text = null;
bool result = text != null && text.Contains("C#");
Console.WriteLine(result); // False
また、null条件演算子を使う方法もあります。
C#string text = null;
bool result = text?.Contains("C#") == true;
Console.WriteLine(result); // False
この書き方では、textがnullの場合でも例外にならず、結果はfalseになります。
実務では、ユーザー入力や外部APIから受け取った値がnullになることがあるため、Containsの前にnull対策をしておくことが重要です。
5-2. LINQのusingがなくてContainsが使えない場合
配列やIEnumerable<T>に対してContainsを使う場合、LINQの拡張メソッドとして提供されることがあります。そのため、using System.Linq;が必要になる場合があります。
C#int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
このコードでContainsが見つからないというエラーが出る場合は、次のusingを追加します。
C#using System.Linq;
完全な例は次のとおりです。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
Console.WriteLine(result);
}
}
エラー例としては、次のような内容が表示されることがあります。
'int[]' does not contain a definition for 'Contains'
この場合は、まずusing System.Linq;があるか確認しましょう。
5-3. List内の独自クラスでContainsが期待どおり動かない原因
独自クラスをListに入れてContainsで検索すると、思ったとおりにtrueにならないことがあります。
C#class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
List<Product> products = new List<Product>
{
new Product { Id = 1, Name = "Book" }
};
Product target = new Product { Id = 1, Name = "Book" };
Console.WriteLine(products.Contains(target)); // Falseになる場合がある
IdもNameも同じなのにfalseになる理由は、既定では同じインスタンスかどうかが比較されるためです。
Listの中に入っているProductと、あとから作成したtargetは、値が同じでも別のオブジェクトです。そのため、Containsでは一致しない場合があります。
このような場合は、条件を指定して検索するAnyを使うのが簡単です。
C#bool exists = products.Any(p => p.Id == target.Id);
Console.WriteLine(exists); // True
また、クラス側でEqualsとGetHashCodeを適切に実装する方法もあります。
5-4. EqualsやIEqualityComparerを使った比較方法
独自クラスでContainsを期待どおりに動かしたい場合、EqualsとGetHashCodeをオーバーライドする方法があります。
C#class Product
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj is Product other)
{
return Id == other.Id;
}
return false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
このようにすると、Idが同じであれば同じ商品として扱えます。
C#List<Product> products = new List<Product>
{
new Product { Id = 1, Name = "Book" }
};
Product target = new Product { Id = 1, Name = "Book" };
Console.WriteLine(products.Contains(target)); // True
また、LINQのContainsには比較方法を指定できるオーバーロードもあります。IEqualityComparer<T>を実装すると、比較ルールを外部に分離できます。
C#class ProductComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
if (x == null || y == null) return false;
return x.Id == y.Id;
}
public int GetHashCode(Product obj)
{
return obj.Id.GetHashCode();
}
}
使い方は次のとおりです。
C#bool exists = products.Contains(target, new ProductComparer());
Console.WriteLine(exists);
単純な条件検索であればAny、オブジェクトの同一性ルールを明確にしたい場合はEqualsやIEqualityComparerを使うとよいでしょう。
6. Containsと似たメソッドの違い
6-1. ContainsとIndexOfの違い
Containsとよく比較されるのがIndexOfです。
Containsは、指定した文字列が含まれているかどうかをtrueまたはfalseで返します。
C#string text = "Hello C#";
bool result = text.Contains("C#");
Console.WriteLine(result); // True
一方、IndexOfは、指定した文字列が最初に見つかった位置を返します。見つからない場合は-1を返します。
C#string text = "Hello C#";
int index = text.IndexOf("C#");
Console.WriteLine(index); // 6
存在するかどうかだけを知りたい場合はContainsのほうが読みやすいです。
C#if (text.Contains("C#"))
{
Console.WriteLine("C#が含まれています");
}
位置が必要な場合はIndexOfを使います。
C#int index = text.IndexOf("C#");
if (index >= 0)
{
Console.WriteLine($"C#は{index}番目にあります");
}
つまり、存在チェックならContains、位置の取得ならIndexOfと考えるとわかりやすいです。
6-2. ContainsとStartsWith・EndsWithの違い
Containsは、文字列のどこかに指定した文字列が含まれていればtrueになります。
C#string fileName = "report_2026.pdf";
Console.WriteLine(fileName.Contains("2026")); // True
StartsWithは、文字列が指定した文字列で始まるかを判定します。
C#Console.WriteLine(fileName.StartsWith("report")); // True
EndsWithは、文字列が指定した文字列で終わるかを判定します。
C#Console.WriteLine(fileName.EndsWith(".pdf")); // True
それぞれの使い分けは次のようになります。
C#string fileName = "report_2026.pdf";
if (fileName.Contains("2026"))
{
Console.WriteLine("2026年のファイルです");
}
if (fileName.StartsWith("report"))
{
Console.WriteLine("レポートファイルです");
}
if (fileName.EndsWith(".pdf"))
{
Console.WriteLine("PDFファイルです");
}
文字列のどこにあってもよい場合はContains、先頭にあることを確認したい場合はStartsWith、末尾にあることを確認したい場合はEndsWithを使いましょう。
6-3. ContainsとAnyの違い
ContainsとAnyはどちらも存在チェックに使えますが、得意な場面が異なります。
Containsは、指定した値そのものが含まれているかを調べるときに使います。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
bool result = numbers.Contains(3);
Console.WriteLine(result); // True
一方、Anyは条件に一致する要素があるかを調べるときに使います。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
bool result = numbers.Any(n => n > 3);
Console.WriteLine(result); // True
文字列のListで部分一致検索をしたい場合は、Anyが便利です。
C#List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
bool result = names.Any(name => name.Contains("li"));
Console.WriteLine(result); // True
Containsは「この値があるか」、Anyは「この条件に合うものがあるか」と考えると使い分けやすいです。
6-4. 完全一致・部分一致・条件付き検索の使い分け
検索処理では、完全一致、部分一致、条件付き検索を使い分けることが大切です。
完全一致は、値が完全に同じかを調べる検索です。
C#List<string> names = new List<string> { "Alice", "Bob" };
bool result = names.Contains("Alice"); // 完全一致
部分一致は、文字列の一部に含まれているかを調べる検索です。
C#string text = "Alice Johnson";
bool result = text.Contains("Alice"); // 部分一致
条件付き検索は、任意の条件に合う要素を探す検索です。
C#List<int> numbers = new List<int> { 10, 20, 30 };
bool result = numbers.Any(n => n >= 20); // 条件付き検索
オブジェクトのListでは、ContainsよりもAnyのほうが使いやすい場面が多いです。
C#List<Product> products = new List<Product>
{
new Product { Id = 1, Name = "Book" },
new Product { Id = 2, Name = "Pen" }
};
bool exists = products.Any(p => p.Id == 2);
このように、単純な値の存在確認にはContains、複雑な条件にはAnyを使うとコードがわかりやすくなります。
7. Containsの実践的な使い方
7-1. 入力文字列に禁止ワードが含まれるか判定する
ユーザーが入力した文字列に禁止ワードが含まれているかを調べる例です。
C#string input = "これはテスト投稿です";
List<string> bannedWords = new List<string> { "禁止", "NG", "spam" };
bool hasBannedWord = bannedWords.Any(word =>
input.Contains(word, StringComparison.OrdinalIgnoreCase));
if (hasBannedWord)
{
Console.WriteLine("禁止ワードが含まれています");
}
else
{
Console.WriteLine("投稿できます");
}
この例では、禁止ワード一覧のいずれかが入力文字列に含まれていればtrueになります。
大文字小文字を無視したい場合は、StringComparison.OrdinalIgnoreCaseを指定すると便利です。
ただし、日本語の表記ゆれや全角半角、ひらがな・カタカナの違いまで考慮する場合は、単純なContainsだけでは不十分なことがあります。必要に応じて正規化や専用のチェック処理を追加しましょう。
7-2. 検索キーワードでListを絞り込む
検索機能では、Listの中からキーワードを含む要素だけを絞り込むことがよくあります。
C#List<string> products = new List<string>
{
"C#入門書",
"JavaScript実践ガイド",
"C#デザインパターン",
"Pythonデータ分析"
};
string keyword = "C#";
List<string> results = products
.Where(product => product.Contains(keyword))
.ToList();
foreach (string product in results)
{
Console.WriteLine(product);
}
実行結果は次のようになります。
C#入門書
C#デザインパターン
大文字小文字を無視した検索にする場合は、次のように書けます。
C#string keyword = "c#";
List<string> results = products
.Where(product => product.Contains(keyword, StringComparison.OrdinalIgnoreCase))
.ToList();
オブジェクトのListを検索する場合も同様です。
C#List<Product> products = new List<Product>
{
new Product { Id = 1, Name = "C#入門書" },
new Product { Id = 2, Name = "JavaScript実践ガイド" },
new Product { Id = 3, Name = "C#デザインパターン" }
};
string keyword = "C#";
List<Product> results = products
.Where(p => p.Name.Contains(keyword))
.ToList();
Containsは、検索キーワードによる絞り込み処理で非常に使いやすいメソッドです。
7-3. 複数条件のいずれかに一致するか調べる
複数のキーワードのうち、いずれかが含まれているかを調べたい場合は、AnyとContainsを組み合わせます。
C#string text = "C#とASP.NET Coreを学習しています";
List<string> keywords = new List<string>
{
"C#",
"Java",
"Python"
};
bool result = keywords.Any(keyword => text.Contains(keyword));
Console.WriteLine(result); // True
この例では、keywordsの中の"C#"がtextに含まれているためtrueになります。
大文字小文字を無視する場合は次のようにします。
C#bool result = keywords.Any(keyword =>
text.Contains(keyword, StringComparison.OrdinalIgnoreCase));
複数条件のすべてに一致するかを調べたい場合は、Allを使います。
C#string text = "C# ASP.NET Core";
List<string> requiredKeywords = new List<string>
{
"C#",
"ASP.NET"
};
bool result = requiredKeywords.All(keyword => text.Contains(keyword));
Console.WriteLine(result); // True
「いずれかに一致」はAny、「すべてに一致」はAllと覚えておくと便利です。
7-4. データ一覧から特定の値を探す
データ一覧から特定の値を探す場合にもContainsは使えます。
たとえば、許可されたIDの一覧に入力IDが含まれているかを確認する例です。
C#List<int> allowedIds = new List<int> { 1001, 1002, 1003 };
int inputId = 1002;
if (allowedIds.Contains(inputId))
{
Console.WriteLine("アクセス可能です");
}
else
{
Console.WriteLine("アクセスできません");
}
文字列のコード一覧をチェックする例もあります。
C#List<string> validCodes = new List<string>
{
"A001",
"B002",
"C003"
};
string inputCode = "B002";
bool isValid = validCodes.Contains(inputCode);
Console.WriteLine(isValid); // True
データが少ない場合はList.Containsで十分です。ただし、何万件、何十万件といった大量データを何度も検索する場合は、HashSet.Containsを検討するとよいでしょう。
8. Containsのパフォーマンスと注意点
8-1. List.Containsは要素数が多いと遅くなる場合がある
List.Containsは便利ですが、要素数が多い場合はパフォーマンスに注意が必要です。
List.Containsは、基本的にListの先頭から順番に要素を確認します。そのため、要素数が増えるほど検索に時間がかかる可能性があります。
C#List<int> numbers = Enumerable.Range(1, 1000000).ToList();
bool result = numbers.Contains(999999);
このような検索を1回だけ行うなら問題にならないことも多いですが、ループの中で何度も実行する場合は処理時間が大きくなることがあります。
C#foreach (int id in inputIds)
{
if (allowedIds.Contains(id))
{
// allowedIdsがListで大量件数の場合、遅くなる可能性がある
}
}
大量データを頻繁に検索する場合は、List以外のコレクションを検討しましょう。
8-2. 高速検索にはHashSet.Containsが有効
特定の値が含まれているかを高速に調べたい場合は、HashSet<T>が有効です。
C#HashSet<int> allowedIds = new HashSet<int> { 1001, 1002, 1003 };
int inputId = 1002;
bool result = allowedIds.Contains(inputId);
Console.WriteLine(result); // True
HashSetは、重複しない値の集合を扱うコレクションです。存在チェックに強く、Containsを頻繁に使う場面で役立ちます。
ListからHashSetに変換することもできます。
C#List<int> allowedIdList = new List<int> { 1001, 1002, 1003 };
HashSet<int> allowedIdSet = allowedIdList.ToHashSet();
bool result = allowedIdSet.Contains(1002);
大量データに対して何度も存在チェックを行う場合は、最初にHashSetへ変換しておくと効率的です。
ただし、HashSetは順序を重視する用途には向きません。順番を保持したい場合はList、検索速度を重視する場合はHashSetというように使い分けましょう。
8-3. 文字列検索でパフォーマンスを意識すべきケース
文字列のContainsも、検索対象が短い文字列であれば通常は大きな問題になりません。
しかし、次のようなケースではパフォーマンスを意識する必要があります。
大量の文章に対して何度も検索する場合、非常に長い文字列を検索する場合、ループ内でToLowerやToUpperを何度も実行する場合、複数キーワードで大量検索する場合などです。
避けたい例は次のようなコードです。
C#foreach (string text in texts)
{
if (text.ToLower().Contains(keyword.ToLower()))
{
Console.WriteLine(text);
}
}
このコードでは、ループのたびにToLowerが実行されます。改善するなら、比較方法を指定する書き方にします。
C#foreach (string text in texts)
{
if (text.Contains(keyword, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(text);
}
}
また、検索キーワード側の変換が必要な場合は、ループの外で一度だけ行うようにしましょう。
C#string lowerKeyword = keyword.ToLower();
foreach (string text in texts)
{
if (text.ToLower().Contains(lowerKeyword))
{
Console.WriteLine(text);
}
}
さらに大規模な全文検索が必要な場合は、Containsだけで実装するのではなく、検索エンジンやデータベースの全文検索機能を使うことも検討しましょう。
8-4. 用途に応じたContainsの使い分け
Containsは便利ですが、どの対象に使うかによって適した書き方が異なります。
文字列に特定のキーワードが含まれているか調べるなら、string.Containsを使います。
C#text.Contains("keyword")
大文字小文字を無視したいなら、StringComparison.OrdinalIgnoreCaseを指定します。
C#text.Contains("keyword", StringComparison.OrdinalIgnoreCase)
Listに特定の値があるか調べるなら、List.Containsを使います。
C#list.Contains(value)
配列やIEnumerable<T>で使うなら、LINQのContainsを使います。
C#array.Contains(value)
複雑な条件で探したいなら、Anyを使います。
C#items.Any(item => item.Id == targetId)
大量データの存在チェックを高速化したいなら、HashSet.Containsを使います。
C#hashSet.Contains(value)
このように、同じContainsでも用途によって最適な使い方は変わります。コードの読みやすさ、検索条件、データ量を考えて選びましょう。
9. C# Containsのよくある質問
9-1. Containsで大文字小文字を無視できますか?
はい、できます。
文字列のContainsで大文字小文字を無視したい場合は、StringComparison.OrdinalIgnoreCaseを指定します。
C#string text = "Hello C#";
bool result = text.Contains("hello", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(result); // True
使用している.NETのバージョンによってこのオーバーロードが使えない場合は、IndexOfを使う方法もあります。
C#bool result = text.IndexOf("hello", StringComparison.OrdinalIgnoreCase) >= 0;
ToLowerやToUpperを使う方法もありますが、比較方法を明確にできるStringComparison.OrdinalIgnoreCaseのほうが実務ではおすすめです。
9-2. Containsで複数の文字列を検索できますか?
Contains単体では、複数の文字列をまとめて指定することはできません。
複数のキーワードのいずれかが含まれているかを調べる場合は、Anyと組み合わせます。
C#string text = "C#と.NETを学習しています";
List<string> keywords = new List<string> { "C#", "Java", "Python" };
bool result = keywords.Any(keyword => text.Contains(keyword));
Console.WriteLine(result); // True
大文字小文字を無視する場合は次のようにします。
C#bool result = keywords.Any(keyword =>
text.Contains(keyword, StringComparison.OrdinalIgnoreCase));
すべてのキーワードが含まれているかを調べたい場合は、Allを使います。
C#bool result = keywords.All(keyword => text.Contains(keyword));
9-3. Containsで完全一致検索はできますか?
文字列のContainsは部分一致検索です。そのため、完全一致検索には向いていません。
C#string text = "JavaScript";
Console.WriteLine(text.Contains("Java")); // True
このように、完全に同じでなくても一部に含まれていればtrueになります。
文字列全体が完全に一致するか調べたい場合は、==やEqualsを使います。
C#string text = "JavaScript";
Console.WriteLine(text == "Java"); // False
Console.WriteLine(text.Equals("JavaScript")); // True
List内の要素として完全一致を調べたい場合は、List.Containsが使えます。
C#List<string> names = new List<string> { "Alice", "Bob" };
Console.WriteLine(names.Contains("Alice")); // True
Console.WriteLine(names.Contains("Ali")); // False
つまり、文字列内の部分一致にはstring.Contains、値そのものの完全一致には==、Equals、List.Containsを使い分けましょう。
9-4. Containsがうまく動かないときは何を確認すべきですか?
Containsが期待どおりに動かないときは、まず検索対象がnullでないか確認しましょう。
C#bool result = text?.Contains("C#") == true;
次に、大文字小文字の違いを確認します。
C#string text = "Hello";
Console.WriteLine(text.Contains("hello")); // False
大文字小文字を無視するなら、次のように書きます。
C#bool result = text.Contains("hello", StringComparison.OrdinalIgnoreCase);
配列でContainsが使えない場合は、using System.Linq;があるか確認しましょう。
C#using System.Linq;
独自クラスのListでContainsがfalseになる場合は、比較方法を確認します。値で比較したいなら、Anyを使うのが簡単です。
C#bool exists = users.Any(user => user.Id == targetId);
大量データで処理が遅い場合は、List.ContainsではなくHashSet.Containsを検討しましょう。
C#HashSet<int> idSet = ids.ToHashSet();
bool exists = idSet.Contains(targetId);
このように、null、大文字小文字、LINQのusing、比較方法、データ量を確認すると、多くの問題を解決できます。
まとめ
C#のContainsは、文字列やList、配列などに指定した値が含まれているかを判定する便利なメソッドです。戻り値はboolで、含まれていればtrue、含まれていなければfalseを返します。
文字列で使う場合は、string.Containsによって部分一致検索ができます。たとえば、文章の中に特定のキーワードが含まれているか、メールアドレスに@が含まれているか、ファイル名に特定の文字列が含まれているかを簡単に調べられます。
Listで使う場合は、List.Containsによって特定の値が存在するかを判定できます。配列で使う場合は、LINQの拡張メソッドとしてContainsを使うため、必要に応じてusing System.Linq;を追加します。
注意点として、string.Containsは基本的に大文字小文字を区別します。大文字小文字を無視したい場合は、StringComparison.OrdinalIgnoreCaseを指定するのがおすすめです。また、nullの文字列に対してContainsを呼び出すと例外になるため、text?.Contains("keyword") == trueのようなnull対策も重要です。
独自クラスのListでContainsを使う場合は、既定の比較方法にも注意が必要です。同じ値を持つオブジェクトでも、別インスタンスであれば一致しないことがあります。その場合は、Anyで条件を指定するか、EqualsやIEqualityComparerを使って比較方法を定義しましょう。
また、List.Containsは要素数が多いと遅くなる場合があります。大量データに対して存在チェックを何度も行う場合は、HashSet.Containsを使うと効率的です。
存在チェックだけならContains、位置を知りたいならIndexOf、先頭や末尾を判定したいならStartsWithやEndsWith、条件付きで検索したいならAnyを使うと、読みやすく保守しやすいコードになります。
C#のContainsはシンプルなメソッドですが、文字列検索、List検索、大文字小文字の扱い、比較方法、パフォーマンスまで理解して使うことで、実務でも安心して活用できます。

