C# LINQ Contains
last modified May 14, 2025
This article explains how to use the LINQ Contains method to check
for the existence of an element within a collection efficiently.
Language-Integrated Query (LINQ) is a powerful feature in C# that enables
seamless querying of data from various sources, such as lists, arrays, and
databases. The Contains method helps determine whether a sequence
contains a specified element, providing a straightforward way to perform
existence checks within collections.
C# LINQ Contains with primitive types
The simplest use of Contains is checking for existence of primitive values in a collection.
int[] numbers = [1, 3, 5, 7, 9, 11, 13];
bool hasFive = numbers.Contains(5);
bool hasTen = numbers.Contains(10);
Console.WriteLine($"Contains 5: {hasFive}");
Console.WriteLine($"Contains 10: {hasTen}");
string[] words = ["sky", "blue", "cloud", "forest", "ocean"];
bool hasBlue = words.Contains("blue");
bool hasRed = words.Contains("red");
Console.WriteLine($"Contains 'blue': {hasBlue}");
Console.WriteLine($"Contains 'red': {hasRed}");
We check for existence of numbers and strings in arrays.
bool hasFive = numbers.Contains(5);
The Contains method returns true if the element is found in the collection.
$ dotnet run Contains 5: True Contains 10: False Contains 'blue': True Contains 'red': False
C# LINQ Contains with custom objects
We can also use Contains with custom objects. To do this, we need
to implement the IEquatable interface in our class. This allows us
to define how two objects of the same type are compared. The Equals
method is overridden to provide custom equality logic.
List<Person> people =
[
new Person("John", "Doe", 25),
new Person("Jane", "Doe", 30),
new Person("Tom", "Smith", 35),
new Person("Alice", "Johnson", 40)
];
var person1 = new Person("John", "Doe", 25);
bool exists1 = people.Contains(person1);
var person2 = new Person("Jane", "Doe", 30);
bool exists2 = people.Contains(person2);
Console.WriteLine($"Person1 exists: {exists1}");
Console.WriteLine($"Person2 exists: {exists2}");
class Person : IEquatable<Person>
{
public string FirstName { get; }
public string LastName { get; }
public int Age { get; }
public Person(string firstName, string lastName, int age)
{
FirstName = firstName;
LastName = lastName;
Age = age;
}
public bool Equals(Person? other)
{
if (other is null) return false;
return FirstName == other.FirstName &&
LastName == other.LastName &&
Age == other.Age;
}
public override bool Equals(object? obj) => Equals(obj as Person);
public override int GetHashCode() => HashCode.Combine(FirstName, LastName, Age);
}
We create a list of Person objects and check for existence of
two persons. The first person is not in the list, while the second one is.
The Person class implements IEquatable to provide
custom equality logic based on first name, last name, and age.
The Equals method is overridden to ensure correct comparison
of Person objects.
$ dotnet run Person1 exists: False Person2 exists: True
C# LINQ Contains with custom comparer
We can provide a custom equality comparer for more complex comparison scenarios.
List<Product> products =
[
new (1, "Laptop", 999.99m),
new (2, "Phone", 699.99m),
new (3, "Tablet", 349.99m),
new (4, "Monitor", 249.99m)
];
var searchProduct = new Product(0, "PHONE", 0); // Different ID and price
// Case-insensitive name comparison
bool exists = products.Contains(searchProduct, new ProductNameComparer());
Console.WriteLine($"Product exists: {exists}");
record Product(int Id, string Name, decimal Price);
class ProductNameComparer : IEqualityComparer<Product>
{
public bool Equals(Product? x, Product? y)
{
if (x == null || y == null) return false;
return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(Product obj) => obj.Name.ToLower().GetHashCode();
}
We check for product existence based only on name (case-insensitive) while ignoring other properties.
bool exists = products.Contains(searchProduct, new ProductNameComparer());
The Contains overload that takes IEqualityComparer
allows custom comparison logic.
$ dotnet run Product exists: True
C# LINQ Contains with query syntax
We can use Contains in LINQ query syntax with the help of the 'where' clause.
List<string> fruits = ["apple", "banana", "orange", "mango", "grape"];
List<string> searchList = ["banana", "grape", "pear"];
var matchingFruits = from fruit in fruits
where searchList.Contains(fruit)
select fruit;
foreach (var fruit in matchingFruits)
{
Console.WriteLine(fruit);
}
We find all fruits that exist in both collections.
where searchList.Contains(fruit)
The Contains method is used within the where clause to filter elements.
$ dotnet run banana grape
C# LINQ Contains vs Any
Contains and Any can both check for element existence but have different use cases.
List<int> numbers = [1, 3, 5, 7, 9];
// Simple existence check - Contains is more appropriate
bool hasFive = numbers.Contains(5);
bool hasFiveWithAny = numbers.Any(n => n == 5);
// Complex condition - Any is required
bool hasEvenNumber = numbers.Any(n => n % 2 == 0);
Console.WriteLine($"Contains 5: {hasFive}");
Console.WriteLine($"Any equal to 5: {hasFiveWithAny}");
Console.WriteLine($"Any even number: {hasEvenNumber}");
Contains is better for simple equality checks while
Any is needed for complex conditions.
bool hasEvenNumber = numbers.Any(n => n % 2 == 0);
Any with a predicate can express conditions that Contains cannot.
$ dotnet run Contains 5: True Any equal to 5: True Any even number: False
Source
In this article we showed how to check for element existence in collections
using LINQ Contains method.
Author
List all C# tutorials.