在C#中高效查询两个List中某属性值相等数据的三种方法

 更新时间:2026年07月03日 08:38:01   作者:hefeng_aspnet  
本文介绍了在C#中高效查询两个List中某属性值相等数据的三种方法:1)使用HashSet配合Where(性能最优,适合大数据量);2)使用Join(适合需要获取双方匹配数据);3)使用Intersect(仅适用于简单类型或重写Equals),需要的朋友可以参考下

在 C# 中查询两个 List 中某个属性值相等的数据(即求交集),最高效且常用的方法是使用 HashSet 配合 LINQ,或者直接使用 LINQ 的 Join 和 Intersect 方法。

以下是几种常见场景的实现方式:

方法一:使用 HashSet + Where(推荐,性能最优)

适用于数据量较大场景。先将其中一个列表的关键属性提取到 HashSet 中,利用其 O(1) 的查找效率进行过滤。

using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public override string ToString() => $"Id: {Id}, Name: {Name}";
    }
    public static void Main()
    {
        var listA = new List<Item>
        {
            new Item { Id = 1, Name = "Apple" },
            new Item { Id = 2, Name = "Banana" },
            new Item { Id = 3, Name = "Cherry" }
        };
        var listB = new List<Item>
        {
            new Item { Id = 2, Name = "Banana" },
            new Item { Id = 4, Name = "Date" },
            new Item { Id = 5, Name = "Elderberry" }
        };
        // 1. 将 ListB 的 Id 放入 HashSet,提高查找效率
        var bIds = new HashSet<int>(listB.Select(b => b.Id));
        // 2. 查询 ListA 中 Id 存在于 HashSet 中的元素
        var commonItems = listA.Where(a => bIds.Contains(a.Id)).ToList();
        Console.WriteLine("属性(Id)相等的数据:");
        foreach (var item in commonItems)
        {
            Console.WriteLine(item);
        }
    }
}

代码说明:

1. 使用 Select 提取 ListB 的 Id 并构建 HashSet,将查找复杂度降为 O(1)。

2. 使用 Where 遍历 ListA,通过 Contains 快速判断是否存在匹配项。

3. 此方法比嵌套循环或多次调用 Any/Contains 性能更高,适合大数据量。

方法二:使用 Join(适合需要获取双方数据)

如果你不仅需要 ListA 中的数据,还需要同时获取 ListB 中匹配的数据,或者进行更复杂的投影,使用 Join 是最直观的方式。

using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public override string ToString() => $"Id: {Id}, Name: {Name}";
    }
    public static void Main()
    {
        var listA = new List<Item>
        {
            new Item { Id = 1, Name = "Apple" },
            new Item { Id = 2, Name = "Banana" },
            new Item { Id = 3, Name = "Cherry" }
        };
        var listB = new List<Item>
        {
            new Item { Id = 2, Name = "Banana" },
            new Item { Id = 4, Name = "Date" }
        };
        // 使用 Join 基于 Id 关联两个列表
        var result = from a in listA
                     join b in listB on a.Id equals b.Id
                     select new 
                     { 
                         ItemA = a, 
                         ItemB = b 
                     };
        Console.WriteLine("Join 查询结果:");
        foreach (var pair in result)
        {
            Console.WriteLine($"A: {pair.ItemA}, B: {pair.ItemB}");
        }
    }
}

代码说明:

1. 使用 LINQ 查询语法或方法语法的 Join 操作,基于指定属性(Id)进行内连接。

2. 可以灵活选择返回 ListA 的对象、ListB 的对象或两者的组合。

3. 底层实现通常也是基于哈希表,性能良好。

方法三:使用 Intersect(仅适用于简单类型或重写 Equals 的自定义类)

如果列表元素是基本类型(如 intstring)或者自定义类重写了 Equals 和 GetHashCode,可以直接使用 Intersect

using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
    // 自定义类需重写 Equals 和 GetHashCode 才能正确使用 Intersect
    public class Item : IEquatable<Item>
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Equals(Item other)
        {
            if (other is null) return false;
            return Id == other.Id;
        }
        public override bool Equals(object obj) => Equals(obj as Item);
        public override int GetHashCode() => Id.GetHashCode();
        public override string ToString() => $"Id: {Id}, Name: {Name}";
    }
    public static void Main()
    {
        var listA = new List<Item>
        {
            new Item { Id = 1, Name = "Apple" },
            new Item { Id = 2, Name = "Banana" }
        };
        var listB = new List<Item>
        {
            new Item { Id = 2, Name = "Banana" },
            new Item { Id = 3, Name = "Cherry" }
        };
        // 直接求交集
        var common = listA.Intersect(listB).ToList();
        Console.WriteLine("Intersect 结果:");
        foreach (var item in common)
        {
            Console.WriteLine(item);
        }
    }
}

代码说明:

1. Intersect 默认使用对象的 Equals 方法比较。

2. 对于自定义类,必须重写 Equals 和 GetHashCode,否则默认比较引用地址,导致无法正确找到逻辑上相等的对象。

3. 此方法简洁,但前提条件较多,不如前两种方法通用。

总结建议

  • 高性能通用方案‌:使用 ‌方法一(HashSet + Where)‌,代码清晰且性能稳定。
  • 需要双向数据‌:使用 ‌方法二(Join)‌。
  • 简单类型或已重写 Equals‌:使用 ‌方法三(Intersect)‌。

以上就是在C#中高效查询两个List中某属性值相等数据的三种方法的详细内容,更多关于C#查询两个List某属性值相等数据的资料请关注脚本之家其它相关文章!

相关文章

  • ActiveMQ在C#中的应用示例分析

    ActiveMQ在C#中的应用示例分析

    这篇文章主要介绍了ActiveMQ在C#中的应用,简单介绍了ActiveMQ的功能、下载及在C#中的具体使用方法,需要的朋友可以参考下
    2016-07-07
  • 一文详解C#多线程同步机制

    一文详解C#多线程同步机制

    在多线程编程中,线程之间的资源共享和并发访问可能导致数据竞争、死锁等严重问题,因此,线程同步机制是保障程序正确性和稳定性的重要手段,本文将从底层原理、使用方式、性能对比等方面对这些机制进行系统性分析,需要的朋友可以参考下
    2025-07-07
  • C#中字符串的加密的源码

    C#中字符串的加密的源码

    C#中字符串的加密的源码...
    2007-03-03
  • C#微信开发之微信公众号标签管理功能

    C#微信开发之微信公众号标签管理功能

    这篇文章主要介绍了C#微信开发之微信公众号标签管理功能 的相关资料,需要的朋友可以参考下
    2016-05-05
  • C#中List转IList的实现

    C#中List转IList的实现

    本文主要介绍了C#中List转IList的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C#实现合并及拆分PDF文件的方法

    C#实现合并及拆分PDF文件的方法

    这篇文章主要为大家详细介绍了C#合并及拆分PDF文件的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C# 通过同步和异步实现优化做早餐的时间

    C# 通过同步和异步实现优化做早餐的时间

    本文以一个简单的小例子—如何做一顿早餐及如何优化做早餐的时间来让大家具体了解一下同步和异步方法的区别,需要的朋友可以参考一下
    2021-12-12
  • C#语言async await之迭代器工作原理示例解析

    C#语言async await之迭代器工作原理示例解析

    这篇文章主要为大家介绍了C#语言async await之迭代器工作原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • C#默认双缓冲技术实例分析

    C#默认双缓冲技术实例分析

    这篇文章主要介绍了C#默认双缓冲技术,实例分析了双缓冲技术的设置与实现技巧,需要的朋友可以参考下
    2015-06-06
  • C#实现json格式数据解析功能的方法详解

    C#实现json格式数据解析功能的方法详解

    这篇文章主要介绍了C#实现json格式数据解析功能的方法,结合实例形式较为详细的分析了C#解析json格式数据的具体操作步骤与相关注意事项,需要的朋友可以参考下
    2017-12-12

最新评论