为什么集合有单独的等于方法

本文关键字:方法 于方法 集合 单独 为什么 | 更新日期: 2023-09-27 18:19:08

在C Sharp .NET中,有一个Equals方法和一个SetEquals方法。区别在哪里?

来自Java,我的第一个想法是SetEquals不是必需的,只需对所有对象使用Equals方法即可。

为什么集合有单独的等于方法

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));

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

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

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

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

HashSet<T>.SetEquals确定哈希集是否包含与给定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

方法忽略重复的条目和 元素在另一个参数中.....

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

  • Equals将测试两个HashSet是否是同一个对象。
  • SetEquals接受一个IEnumerable<T>,它的作用是:">SetEquals 方法忽略重复条目和元素在其他参数中的顺序。

因此,SetEquals用于测试以查看您是否将IEnumerable加载到HashSet中,它是否会生成与您的源相同的HashSet。

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

SetEquals:

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

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

等于:

等于实际上是一个参考测试

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.
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);
        }

产生输出:等于方法返回假SetEquals 方法返回 True

因此,equals方法似乎是对参照相等的测试。

实现

ISet<T>.SetEquals

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

继承

objectEquals实现

等效于对 ReferenceEquals 方法的调用。

继承的 ReferenceEquals 实现,

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


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


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