Linq Contains() 是否会检查 HashSet?

13
有时候,一个HashSet会通过属性作为IEnumerable暴露出来。
众所周知,对于enumerable.Count(),代码会检查它是否是一个集合,因此它不会枚举整个列表,而是采取捷径。
在使用Linq版本的enumerable.Contains(x)和HashSets时,是否有类似的检查?

3
为什么不自己看一下:http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs - Selman Genç
你的意思是什么?如果在查询中调用contains(x),它只会检查列表的一部分吗? - terrybozzio
@TravisJ的意思是Enumerable.Count()会检查对象是否为ICollection类型,如果是,则返回ICollection.Count以进行优化。如果不是,则必须枚举可枚举对象以计算项数。 - cdhowie
@TravisJ ICollection 还有一个 Contains 方法,可以实现专门的逻辑。例如,在 HashSet<T> 的情况下,它可以在平均 O(1) 时间内执行测试,而不是枚举元素直到找到匹配项。 - cdhowie
没问题,根据下面的答案,我的假设是错误的。我想表达的是HashSet是一个唯一对象的集合,所以我本来猜测HashSet已经重载了Contains而不是使用ICollection中的方法。 - Maurice Reeves
显示剩余5条评论
2个回答

18

参考源代码来看,是的,虽然不是直接实现:

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) {
    ICollection<TSource> collection = source as ICollection<TSource>;
    if (collection != null) return collection.Contains(value);
    return Contains<TSource>(source, value, null);
}

如果源可枚举实现了 ICollection<T> (并且HashSet<T>就是这样),它将使用集合的 Contains方法。

2
+1 但我要指出它并没有特别检查HashSet<T>(因为这是被问到的问题),但它将检查ICollection<T>,因此可以在不需要专业知识的情况下完成相同的任务。 - cdhowie

1
注意,文档中也记录了查找ICollection<T>(请参阅备注)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接