26

In C Sharp .NET there is a Equals method and a SetEquals method. Where is the difference?

Coming from Java, my first thought was that SetEquals is not necessary, just use the Equals method for all objects.

4

7 回答 7

37

SetEquals不遵守与 相同的合同Equals。特别是它不是对称的,因为参数只是IEnumerable<T>而不是ISet<T>. 这允许您在只有一个集合时检查集合是否相等。考虑:

List<int> intList = new List<int> { 1, 2, 3 };
HashSet<int> intSet = new HashSet<int>(intList);

现在我们可以使用:

Console.WriteLine(intSet.SetEquals(intList));

...但是如果不对所有其他实现Equals强制执行相同的行为,我们就无法以相同的方式实现。List<int>IEnumerable<T>

即使我们将它限制在其他集合中,还有一个有趣的问题是平等的真正含义。例如,考虑两个HashSet<string>包含相同字符串但具有不同相等比较器的集合。(也许一个区分大小写,一个不区分。)它们是否相等?SetEquals通过避免过于笼统,设法避免此类哲学问题。

aHashSet<int>和 aSortedSet<int>呢?他们能平等吗?它们可以具有相同的值 - 但一个的顺序是未定义的。

Object.Equals总的来说,在我看来,和的想法Object.GetHashCode太宽泛了。通常你想要一种特定类型的相等——而且通常首先比较对象是否相等是没有意义的。这很容易成为一个完全不同的咆哮的主题,但与此同时,我至少很高兴 .NET 没有尝试将这个过于宽泛的想法应用于集合。IMO,以明确定义的含义使用的能力SetEquals更有用。

于 2013-06-20T14:04:00.767 回答
13

HashSet<T>.SetEquals确定 HashSet 是否包含与给定 相同的元素IEnumerable<T>。但是,如果类型不同,为什么要返回 true 呢?

HashSet<int> h = new HashSet<int>();
h.Add(0);
h.Add(1);
int[] ints = new[] { 0, 1, 1, 0 };
h.SetEquals(ints); // true, ignores duplicates because it's a set
h.Equals(ints); // false, correct because not even the same types

MSDN

SetEquals 方法忽略重复条目和其他参数中的元素顺序.....

由于HasetSet<T>不覆盖Equals它使用从仅比较引用的对象继承的那个。因此,如果两个对象不是相同的引用,它会返回false

于 2013-06-20T14:04:39.673 回答
8
  • Equals将测试两个HashSets 是否是同一个对象。
  • SetEquals接受 a IEnumerable<T>,它的作用是:“SetEquals 方法忽略重复条目和另一个参数中元素的顺序。”

SetEquals测试是否将 IEnumerable 加载到 HashSet 中也是如此,它是否会生成与源相同的 HashSet 。

于 2013-06-20T14:04:58.233 回答
3

Equals检查两者之间的引用相等性SetEquals并将检查集合中的元素。

于 2013-06-20T14:04:02.943 回答
0
public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            System.Collections.Generic.HashSet<int> setA= new System.Collections.Generic.HashSet<int>();
            setA.Add(1);
            System.Collections.Generic.HashSet<int> setB= new System.Collections.Generic.HashSet<int>();
            setB.Add(1);


            Console.WriteLine("Equals method returns {0}", setA.Equals(setB));
            Console.WriteLine("SetEquals method returns {0}", setA.SetEquals(setB));


            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }

产生输出:Equals 方法返回 False SetEquals 方法返回 True

因此,equals 方法似乎是对引用相等性的测试。

于 2013-06-20T14:16:14.167 回答
0

ISet<T>.SetEquals实施_

确定当前集合和指定集合是否包含相同的元素。

Equals继承自的实现object

相当于调用 ReferenceEquals 方法。

继承的ReferenceEquals实现,

确定指定的 Object 实例是否为同一个实例。


特别要注意,IEnumerable<T>传递给的序列SetEquals可以具有集合中每个成员的一个或多个实例,以任何顺序,并且SetEquals仍将返回 true。


如果您想确认两个序列以相同的顺序包含完全相同的成员,您可以使用SequenceEqual扩展。

于 2013-06-20T14:11:16.003 回答
0

设置等于:

检查 HashSet 是否包含与给定IEnumerable<T>相同的元素。

SetEquals 方法将第二个集合视为没有重复元素。如果存在重复元素,则两个集合仍可能被视为相等。

等于:

Equals 实际上是一个参考测试

List<string> stringList = new List<string> { "a", "b", "c" };
SortedSet<string> stringSet = new SortedSet<string> { "a", "b", "c" };

bool a = stringSet.SetEquals(stringList );
// See if the two collections contain the same elements.
于 2013-06-20T14:09:20.437 回答