C#高级:利用LINQ进行实体列表的集合运算

问题引入:

bash 复制代码
Teacher实体的唯一标识符是Name和Classes字段(或者说这两个字段唯一确定一条数据),如何对两个实体列表做交集、差集运算呢?(并集直接调用AddRange方法即可)

一、重写方法实现

1.原理

重写 Equals() 和 GetHashCode() 方法,使用Intersect() 和 Except() 方法在比较时就会基于这些字段来判断对象是否相等

2.快速生成代码

3.代码

cs 复制代码
public class Teacher
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Classes { get; set; }

    public override bool Equals(object obj)
    {
        return obj is Teacher teacher &&
               Name == teacher.Name &&
               Classes == teacher.Classes;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Classes);
    }
}

class Program
{
    static void Main()
    {
        // 创建两个示例列表
        List<Teacher> listA = new List<Teacher>
        {
            new Teacher { Id = 1, Name = "Alice", Classes = "Math" },
            new Teacher { Id = 2, Name = "Bob", Classes = "Science" },
            new Teacher { Id = 3, Name = "Charlie", Classes = "English" }
        };

        List<Teacher> listB = new List<Teacher>
        {
            new Teacher { Id = 2, Name = "Bob", Classes = "Science" },
            new Teacher { Id = 3, Name = "Charlie", Classes = "English" },
            new Teacher { Id = 4, Name = "David", Classes = "History" }
        };

        // 求交集
        var intersection = listA.Intersect(listB).ToList();

        // 求差集 A - B
        var difference = listA.Except(listB).ToList();


        // 输出结果
        Console.WriteLine("交集:");
        foreach (var teacher in intersection)
        {
            Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");
        }

        Console.WriteLine("\n差集 A - B:");
        foreach (var teacher in difference)
        {
            Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");
        }
    }
}

二、嵌套查询实现

1.原理

cs 复制代码
var intersection = listA.Where(a => listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();
var difference = listA.Where(a => !listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();

where-Any相当于A表内连接B表( A ∩ B );

where-!Any相当于A表左外连接B表并剔除匹配到的数据(A - B)。

2.代码

cs 复制代码
public class Teacher
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Classes { get; set; }
}

class Program
{
    static void Main()
    {
        // 创建两个示例列表
        List<Teacher> listA = new List<Teacher>
        {
            new Teacher { Id = 1, Name = "Alice", Classes = "Math" },
            new Teacher { Id = 2, Name = "Bob", Classes = "Science" },
            new Teacher { Id = 3, Name = "Charlie", Classes = "English" }
        };

        List<Teacher> listB = new List<Teacher>
        {
            new Teacher { Id = 2, Name = "Bob", Classes = "Science" },
            new Teacher { Id = 3, Name = "Charlie", Classes = "English" },
            new Teacher { Id = 4, Name = "David", Classes = "History" }
        };

        // 自定义方法来比较 Name 和 Classes
        var intersection = listA.Where(a => listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();
        var difference = listA.Where(a => !listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();

        // 输出交集
        Console.WriteLine("交集:");
        foreach (var teacher in intersection)
        {
            Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");
        }

        // 输出差集
        Console.WriteLine("\n差集 A - B:");
        foreach (var teacher in difference)
        {
            Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");
        }
    }
}
相关推荐
椒颜皮皮虾྅6 小时前
OpenVINO C# API 3.3.1:支持OpenVINO 2026.3及GenAI增强
人工智能·c#·openvino
半亩码田9 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#
唐青枫16 小时前
别再手写 args[0]:C#.NET CommandLineParser 命令行工具实战详解
c#·.net
LccKyI17 小时前
C#学习day06(方法/函数及其关键字,附思维导图)
经验分享·学习·c#
.Peter17 小时前
.NET/WPF 程序在部分 Windows 电脑无法保存用户环境变量:使用 DPAPI 实现安全兼容
windows·信息安全·c#·.net·wpf·环境变量·dpapi
农村小镇哥18 小时前
怎么把HTM格式转化成WORD
ui·c#·word
农村小镇哥18 小时前
C#读取CSV文件的方法
服务器·数据库·c#
FuckPatience19 小时前
C# 报错参数无效
c#
北域码匠1 天前
PID 控制算法完整详解(C# 原生实现,无第三方库)
c#·pid控制·工控开发·闭环控制·自动控制算法·数字pid·增量式pid
离陌在学C#1 天前
C# 重载与重写:深入理解面向对象编程的核心概念
java·c#