我很好奇.. 当我在 HashSet 上调用 Distinct<>() (来自 Linq),.NET 是否知道这个 IEnumerable 总是包含一组不同的值,并优化掉这个调用?
从 Reflector 看代码来看,我必须说不行。
无论你给它什么类型,代码最终都会构造一个迭代器方法生成的类的实例。
这个问题也受到了这样一个事实的影响,即您可以为 Hashset 和 Distinct 方法指定比较对象,这意味着优化只会在很少的情况下使用。
例如,在以下情况下,它实际上可以优化调用,但它无法知道:
var set = new HashSet<int>(new MyOwnInt32Comparer());
var distinct = set.Distinct(new MyOwnInt32Comparer());
因为我给它两个比较器类的实例,而这种类通常不实现相等性方法,所以Distinct方法无法知道两个比较器实现实际上是相同的。
无论如何,这是一个程序员比运行时更了解代码的情况,所以要利用它。 Linq可能非常好,但它并非全能,所以要善用自己的知识。
HashSet<T>
。底层迭代器在枚举期间创建一个新的集合并填充它,因此开销应该不会太大。