对 HashSet<T> 调用 Distinct<>() 方法

6

我很好奇.. 当我在 HashSet 上调用 Distinct<>() (来自 Linq),.NET 是否知道这个 IEnumerable 总是包含一组不同的值,并优化掉这个调用?

3个回答

11

从 Reflector 看代码来看,我必须说不行。

无论你给它什么类型,代码最终都会构造一个迭代器方法生成的类的实例。

这个问题也受到了这样一个事实的影响,即您可以为 Hashset 和 Distinct 方法指定比较对象,这意味着优化只会在很少的情况下使用。

例如,在以下情况下,它实际上可以优化调用,但它无法知道:

var set = new HashSet<int>(new MyOwnInt32Comparer());
var distinct = set.Distinct(new MyOwnInt32Comparer());

因为我给它两个比较器类的实例,而这种类通常不实现相等性方法,所以Distinct方法无法知道两个比较器实现实际上是相同的。

无论如何,这是一个程序员比运行时更了解代码的情况,所以要利用它。 Linq可能非常好,但它并非全能,所以要善用自己的知识。


2
我认为不需要,因为Enumerable类的distinct方法的输入参数是IEnumerable类型,并没有特定的判断它是否为哈希集合的方法(所以不会有任何操作)。

2
不,从反射实现来看,它并没有检查枚举是否为 HashSet<T>。底层迭代器在枚举期间创建一个新的集合并填充它,因此开销应该不会太大。

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