ToHashSet()方法会自动删除重复项而不会引发错误吗?

3
我发现的Microsoft文档没有清楚地回答我的问题,因为它没有明确指出ToHashSet()会如何处理重复项。
它们是否包含在内?被移除了吗?还是会触发错误?
在我的搜索和测试中,似乎重复项被静默地剥离。StackOverflow上的其他问题假定应该剥离重复项。
只要正确覆盖.Equals().GetHashCode(),这对于所有对象都是正确的。
我是正确的还是错过了什么?假设会导致错误。 一个简单的回答,带有文档链接的Yes就足够了。
引发此问题的两个原因是:
1. ToDictionary的文档特别指出重复项会引发错误。 .ToHashSet()的文档没有关于重复项的说明。
2. 看到调用.ToHashSet()之前进行.Distinct().GroupBy()的代码。这意味着开发人员要么不理解.ToHashSet(),要么害怕创建错误。
1个回答

7

根据定义,集合中不可能包含重复的元素。

.NET方法记录了它们可能引发的异常。 ToHashSet()没有列出任何异常,因此我们可以安全地假设它不会抛出任何异常。

ToHashSet()确实有两种可能的实现方式:

  1. 将任务委托给这个HashSet构造函数。文档的“备注”部分说明:

如果collection包含重复项,则集合将包含每个唯一元素的一个。不会抛出任何异常。因此,生成的集合的大小与集合的大小不相同。

因此,相同的元素被简单地跳过。这确实是在源代码中使用的实现。

  1. 它枚举源序列并在最初为空的集合上重复调用Add。由于它指定返回:

如果将元素添加到HashSet<T>对象,则为true; 如果元素已经存在,则为false

在任何情况下,都不会抛出异常。重复项被忽略,生成的集合仅包含唯一元素。


可以在C#交互式中测试:new[] { 1, 1, 2 }.ToHashSet() 的结果是 HashSet<int>(Count = 2) { 1, 2 } - Pasi Savolainen
1
".NET 方法文档中记录了它们可能引发的异常。然而,这通常不是详尽无遗的。例如,文档从未说明可能引发StackOverflowExceptionThreadAbortException,尽管每个方法理论上都可能引发这些异常。文档经常遗漏深层调用中的异常,也忽略了DivideByZeroException。由于文档可能不完整,并且没有明确排除 ToHashSet() 可能会在调用 Add() 后返回 false 并抛出异常的情况(这是一个有效的第三种实现方式),所以提问者对预期行为的询问是正确的。" - Sean Werkema

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