首页 / 教程列表 / LINQ教程 / LINQ操作符之Contains

LINQ操作符之Contains

3070 更新于: 2022-03-24 读完约需 13 分钟

前言

在这篇文章中,我们将用一些例子来讨论C#中LINQ的Contains操作符。Contains操作符检查指定的元素是否存在于集合中,并返回一个布尔值。
Contains扩展方法有两个重载,第一个重载方法需要传入一个在集合中检索的值,第二个重载方法需要传入一个附加的IEqualityComparer参数来进行自定义的相等性比较器。

Contains的重载方法定义如下:

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value);

public static bool Contains<TSource>(this IEnumerable<TSource> source, 
                                     TSource value, 
                                    IEqualityComparer<TSource> comparer);

如上所述,Contains()扩展方法需要一个值作为输入参数进行检查。值的类型必须与泛型集合的类型相同。

下面我们以具体示例来说明Contains操作符的用法。

LINQ中的Contains操作符

以下程序片段演示用Contains检查集合numbers中是否存在8和10。

请注意:泛型集合numbers的类型为int

using System;
using System.Linq;

namespace LinqTutorial
{
    public class MyProgram
    {
        static void Main(string[] args)
        {
            // 定义一个变量名为numbers的数组
            var numbers = new[] { 1, 3, 8, 16, 20, 30, 56, 80 };
            // 检查numbers数组中是否包含数字8
            var result1 = numbers.Contains(8);
            Console.WriteLine(result1); // 打印结果为:True

            // 检查numbers数组中是否包含数字10
            var result2 = numbers.Contains(10);
            Console.WriteLine(result2); // 打印结果为:False

            Console.Read();
        }
    }
}

复杂类型的Contains操作

以上示例中,使用Contains检查.NET原始数据类型是没有任何问题的,但不适用于用户自定义类。
在开始演示之前,我们先创建一个Student类,如下:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

下面,我们使用Contains方法来检查集合students中是否存在与指定std相同的元素,示例代码如下:

using System;
using System.Collections.Generic;

namespace LinqTutorial
{
    public class MyProgram
    {
        static void Main(string[] args)
        {
            // 创建一个Students集合
            var students = new List<Student>
            {
                new() {Id = 1,Name = "John",Age = 16},
                new() {Id = 2,Name = "Steve",Age = 15},
                new() {Id = 3,Name = "James",Age = 17},
                new() {Id = 4,Name = "Anna",Age = 18},
                new() {Id = 5,Name = "Alex",Age = 16}
            };
            // 定义一个要查找的Student
            var std = new Student { Id = 3, Name = "James", Age = 17 };
            // 使用Contains方法检查是否存在相同的Student元素
            var result = students.Contains(std);
            Console.WriteLine(result); // 输出:False
            Console.Read();
        }
    }
}

正如你在上面的例子中看到的,即使students集合中包含要查找的目标James,但Contains仍然返回False

这是因为Contains扩展方法只比较对象的引用,而不是对象的实际值。因此,为了比较student对象的值,需要通过实现IEqualityComparer接口创建一个类,该接口比较两个student对象的值并返回布尔值。

下面是一个实现了IEqualityCompare接口的StudentComparer类,它的Equals()方法实现了比较两个Student对象的值:

public class StudentCompare : IEqualityComparer<Student>
{
    public bool Equals(Student x, Student y)
    {
        if (ReferenceEquals(x, y))
        {
            return true;
        }

        if (x is null || y is null)
        {
            return false;
        }

        return x.Id == y.Id && x.Name == y.Name && x.Age == y.Age;
    }

    public int GetHashCode(Student obj)
    {
        var idHashCode = obj.Id.GetHashCode();
        var nameHashCode = obj.Name.GetHashCode();
        var ageHashCode = obj.Age.GetHashCode();

        return idHashCode ^ nameHashCode ^ ageHashCode;
    }
}

调用Contains的有IEqualityCompare参数的方法进行查找,示例代码如下:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqTutorial
{
    public class MyProgram
    {
        static void Main(string[] args)
        {
            // 创建一个Students集合
            var students = new List<Student>
            {
                new() {Id = 1,Name = "John",Age = 16},
                new() {Id = 2,Name = "Steve",Age = 15},
                new() {Id = 3,Name = "James",Age = 17},
                new() {Id = 4,Name = "Anna",Age = 18},
                new() {Id = 5,Name = "Alex",Age = 16}
            };
            // 定义一个要查找的Student
            var std = new Student { Id = 3, Name = "James", Age = 17 };
            // 使用Contains方法检查是否存在相同的Student元素
            var result = students.Contains(std, new StudentCompare());
            Console.WriteLine(result); // 输出:True
            Console.Read();
        }
    }
}

总结

本文主要分享学习了C#中LINQ的Contains操作符,它有两个重载。对于.NET原始数据类型(比如:int,decimal,double,float等等),可直接传入要查找的值,但对于自定义类的查找,需实现IEqualityCompare接口。

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

本文永久链接码友网 » LINQ教程 » LINQ操作符之Contains 分享:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册