ZetCode

C# LINQ Contains

最后修改于 2025 年 5 月 14 日

本文解释了如何使用 LINQ 的 Contains 方法有效地检查集合中是否存在元素。

语言集成查询 (LINQ) 是 C# 中的一项强大功能,可以无缝地查询来自各种来源的数据,例如列表、数组和数据库。 Contains 方法有助于确定序列是否包含指定的元素,从而提供了一种在集合中执行存在性检查的简单方法。

C# LINQ Contains 与基本类型

Contains 最简单的用法是检查集合中是否存在基本值。

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}");

我们检查数组中是否存在数字和字符串。

bool hasFive = numbers.Contains(5);

如果在集合中找到该元素,则 Contains 方法返回 true。

$ dotnet run 
Contains 5: True
Contains 10: False
Contains 'blue': True
Contains 'red': False

C# LINQ Contains 与自定义对象

我们也可以将 Contains 用于自定义对象。 为此,我们需要在我们的类中实现 IEquatable 接口。 这允许我们定义如何比较同一类型的两个对象。 重写 Equals 方法以提供自定义的相等性逻辑。

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);
}

我们创建一个 Person 对象列表,并检查是否存在两个人。 第一个人不在列表中,而第二个人在。 Person 类实现了 IEquatable,以基于名字、姓氏和年龄提供自定义的相等性逻辑。 重写 Equals 方法以确保正确比较 Person 对象。

$ dotnet run 
Person1 exists: False
Person2 exists: True

C# LINQ Contains 与自定义比较器

我们可以为更复杂的比较场景提供自定义的相等性比较器。

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();
}

我们仅基于名称(不区分大小写)检查产品是否存在,而忽略其他属性。

bool exists = products.Contains(searchProduct, new ProductNameComparer());

采用 IEqualityComparerContains 重载允许自定义比较逻辑。

$ dotnet run 
Product exists: True

C# LINQ Contains 与查询语法

我们可以借助 'where' 子句在 LINQ 查询语法中使用 Contains。

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);
}

我们找到两个集合中都存在的所有水果。

where searchList.Contains(fruit)

Contains 方法在 where 子句中使用,以过滤元素。

$ dotnet run 
banana
grape

C# LINQ Contains 与 Any

Contains 和 Any 都可以检查元素是否存在,但具有不同的用例。

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 更适合简单的相等性检查,而对于复杂的条件,则需要 Any

bool hasEvenNumber = numbers.Any(n => n % 2 == 0);

带有谓词的 Any 可以表达 Contains 无法表达的条件。

$ dotnet run 
Contains 5: True
Any equal to 5: True
Any even number: False

来源

Enumerable.Contains 方法

在本文中,我们展示了如何使用 LINQ 的 Contains 方法检查集合中是否存在元素。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。 至今,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程