ZetCode

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.

Program.cs
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.

Program.cs
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.

Program.cs
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.

Program.cs
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.

Program.cs
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

Enumerable.Contains Method

In this article we showed how to check for element existence in collections using LINQ Contains method.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.