SetEquals 不遵守与Equals 相同的合同。特别是它不是对称的,因为参数只是IEnumerable<T> 而不是ISet<T>。这允许您在仅设置 one 时检查设置是否相等。考虑:
List<int> intList = new List<int> { 1, 2, 3 };
HashSet<int> intSet = new HashSet<int>(intList);
现在我们可以使用:
Console.WriteLine(intSet.SetEquals(intList));
...但是如果不对List<int> 和所有其他IEnumerable<T> 实现强制执行相同的行为,我们就无法以相同的方式实现Equals。
即使我们将其限制在其他集合中,也存在一个有趣的问题,即平等的真正含义。例如,考虑两个 HashSet<string> 集合,它们包含相同的字符串,但具有不同的相等比较器。 (也许一个区分大小写,一个不区分。)它们是否相等? SetEquals 通过避免过于笼统来设法避免此类哲学问题。
HashSet<int> 和 SortedSet<int> 怎么样?他们能平等吗?它们可以具有相同的值 - 但一个的顺序是不确定的。
总的来说,Object.Equals 和Object.GetHashCode 的想法在我看来太宽泛了。通常你想要一个特定的type 相等 - 而且通常首先比较对象是否相等是没有意义的。这很容易成为一个完全不同的咆哮的主题,但与此同时,我至少很高兴 .NET 没有尝试将这个过于宽泛的想法应用于集合。 IMO,使用具有明确含义的SetEquals 的能力更有用。