Does Linq Contains() check for HashSet?
有时哈希集通过属性作为IEnumerable公开。
众所周知,对于enumerable.Count(),代码检查它是否是一个集合,因此它不会枚举整个列表,而是采用一种快捷方式。
使用enumerable.Contains(x)和hashset的linq版本有没有类似的检查?
- Count()的快捷方式是一个属性。属性如何正确返回动态表达式的布尔值?
- 为什么不看看你自己:referencesource.microsoft.com/system.core/system/linq/…
- 你到底什么意思?….如果一个查询中的调用包含(x),则只检查列表的一部分?
- @travisj他是指Enumerable.Count()检查对象是否为ICollection类型,如果是,则返回ICollection.Count作为优化。如果不是这样的话,它必须枚举可枚举的以便对项目进行计数。
- @是的,我了解这方面,但这与Contains有什么关系?
- 看来至少Mono能做到这一点。(集合类型应该实现ICollection,因此这称为集合的ICollection.Contains()实现。)如果ms.net也这样做,我不会感到惊讶。
- @Travisj ICollection也有一个可以实现专门逻辑的Contains方法,例如在HashSet的情况下,它可以在平均O(1)时间内执行测试,而不是在找到匹配之前枚举元素。
- 我不认为它会这样做,因为哈希集是唯一对象的集合,所以它需要知道集合中已经存在哪些对象。我认为contains会检查已经插入对象的映射。最好的办法是检查引用源。
- @毛里塞耶夫斯,我不能把你的话前后颠倒。
- 好吧,根据下面的答案,我的假设是错误的。我想说的是,hashset是一个唯一对象的集合,所以我猜想hashset已经重载了contains,没有使用来自ICollection的方法。
从参考源来看,是的,虽然不是直接:
1 2 3 4 5
| 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);
} |
如果源Enumerable实现ICollection(和HashSet实现),则使用集合的Contains方法。
- +1但我要指出的是,它不是专门检查HashSet(这是所问的问题),而是检查ICollection,因此不需要对HashSet有专门的知识就可以完成相同的事情。
注:还记录了查找ICollection(见备注)。