如何用LINQ的Intersect/IntersectBy实现不同类型列表交集并返回ListA类型?
使用IntersectBy(推荐,.NET 6+)
从.NET 6开始,IntersectBy是最简洁高效的方案,直接通过指定匹配键实现需求:
List<ListA> intersect = listA.IntersectBy(listB, item => item.Id).ToList();
原理:
IntersectBy接收两个核心参数:用于匹配的键集合(listB中的string类型Id),以及从listA元素中提取匹配键的委托(item => item.Id)- 内部会将
listB转为哈希集合,再遍历listA筛选出Id存在于该哈希集合中的元素,时间复杂度为O(n+m),比你原有的Where+Any(O(n*m))性能更优
使用Intersect配合自定义比较器(兼容.NET 5及更早版本)
如果你的项目不支持.NET 6+,可以通过自定义相等比较器结合Intersect实现:
首先定义比较器,指定仅通过Id属性比较ListA对象:
public class ListAIdEqualityComparer : IEqualityComparer<ListA> { public bool Equals(ListA x, ListA y) { if (x == null || y == null) return false; return x.Id == y.Id; } public int GetHashCode(ListA obj) { return obj?.Id.GetHashCode() ?? 0; } }
然后将listB的string Id包装为临时ListA对象,再调用Intersect:
var tempListB = listB.Select(id => new ListA { Id = id }); List<ListA> intersect = listA.Intersect(tempListB, new ListAIdEqualityComparer()).ToList();
说明:
- 因为
Intersect要求两个集合元素类型一致,所以需要把listB的string转为ListA临时对象 - 自定义比较器让
Intersect只关注Id属性,忽略对象引用和其他属性
对比你原有的Where(x => listB.Any(y => y == x.Id))写法,IntersectBy不仅代码更简洁,还优化了性能,推荐优先使用。
内容的提问来源于stack exchange,提问作者bob mason
相关产品推荐
相关产品推荐

