List<T>.Contains() / IndexOf()
| Since: | C# 2.0(2005) |
|---|
The Contains() method checks whether a list contains a specified element, and IndexOf() returns the index of the first occurrence of an element.
Syntax
using System.Collections.Generic; // Returns true if the specified element exists in the list. list.Contains(T item) list.IndexOf(T item) // Starts searching from startIndex. list.IndexOf(T item, int startIndex) list.LastIndexOf(T item)
Method List
| Method | Description |
|---|---|
| Contains(T item) | Returns true if the list contains item. Searches sequentially, so the time complexity is O(n). |
| IndexOf(T item) | Returns the index of the first occurrence of item. Returns -1 if not found. |
| IndexOf(T item, int startIndex) | Starts searching from startIndex and returns the index of the first matching element. |
| LastIndexOf(T item) | Returns the index of the last occurrence of item. Returns -1 if not found. |
Sample Code
Use Contains() to check for element existence, and IndexOf() to get the index.
Program.cs
using System;
using System.Collections.Generic;
List<string> languages = new List<string> { "C#", "Java", "Python", "Java", "Go" };
Console.WriteLine(languages.Contains("Python")); // True
Console.WriteLine(languages.Contains("Swift")); // False
if (languages.Contains("C#"))
{
Console.WriteLine("C# is in the list.");
}
Console.WriteLine(languages.IndexOf("Java")); // 1
Console.WriteLine(languages.IndexOf("Swift")); // -1
Console.WriteLine(languages.LastIndexOf("Java")); // 3
This produces the following output:
dotnet run True False C# is in the list. 1 -1 3
Detecting Duplicate Elements with IndexOf()
Using both IndexOf() and LastIndexOf() lets you check whether the same value appears more than once. If the indices differ, duplicates exist.
DuplicateCheck.cs
using System;
using System.Collections.Generic;
List<string> languages = new List<string> { "C#", "Java", "Python", "Java", "Go" };
int firstIdx = languages.IndexOf("Java");
int lastIdx = languages.LastIndexOf("Java");
if (firstIdx != lastIdx)
{
Console.WriteLine($"Java appears more than once (at indices {firstIdx} and {lastIdx}).");
}
// Find the next occurrence using startIndex
int next = languages.IndexOf("Java", firstIdx + 1);
Console.WriteLine($"Next Java index: {next}"); // 3
This produces the following output:
dotnet run Java appears more than once (at indices 1 and 3). Next Java index: 3
Practical Pattern: Validating User Input Against Allowed Choices
Contains() provides a concise way to check whether a user's input matches one of the valid choices.
ValidateSample.cs
using System;
using System.Collections.Generic;
List<string> validChoices = new List<string> { "start", "settings", "quit" };
string[] inputs = { "start", "help", "quit" };
foreach (string input in inputs)
{
if (validChoices.Contains(input))
{
Console.WriteLine($"'{input}' is a valid choice.");
}
else
{
Console.WriteLine($"'{input}' is not a valid choice.");
}
}
This produces the following output:
dotnet run 'start' is a valid choice. 'help' is not a valid choice. 'quit' is a valid choice.
Common Mistakes
Common Mistake: Using List.Contains() for Frequent Lookups Hurts Performance
Contains() and IndexOf() are O(n) operations — they scan the list from the beginning each time. For large datasets with frequent lookups, use HashSet<T> or Dictionary<TKey, TValue>, which support O(1) lookups.
using System; using System.Collections.Generic; // NG: using List.Contains() for frequent searches on large data List<int> bigList = new List<int>(); for (int i = 0; i < 100000; i++) bigList.Add(i); // Contains() scans from the beginning every time (O(n)) Console.WriteLine(bigList.Contains(99999)); // True (slow)
The corrected version looks like this:
using System; using System.Collections.Generic; // OK: HashSet<T> supports O(1) lookups HashSet<int> bigSet = new HashSet<int>(); for (int i = 0; i < 100000; i++) bigSet.Add(i); Console.WriteLine(bigSet.Contains(99999)); // True (fast)
This produces the following output:
dotnet run True True
When element order is irrelevant and you only need existence checks, HashSet<T> is a better fit. For details, see HashSet<T>.
Notes
Both Contains() and IndexOf() scan the list from the beginning, so they take time proportional to the number of elements (O(n)). If you need frequent lookups, consider using Dictionary<TKey, TValue> or HashSet<T> instead. These support O(1) lookups.
For sorting and iterating over a list, see List<T>.Sort() / Reverse() / ForEach().
If you find any errors or copyright issues, please contact us.