IEqualityComparer和IEquatable在Enumerable.SequenceEqual方法中的作用是什么?[英] What are the roles of IEqualityComparer and IEquatable in the Enumerable.SequenceEqual method

本文是小编为大家收集整理的关于IEqualityComparer和IEquatable在Enumerable.SequenceEqual方法中的作用是什么?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在此页面上的 msdn 他们描述了Enumerable类的SequenceEqual方法.

沿着页面中的一半说:

如果要比较序列中对象的实际数据 您不仅要比较他们的参考,还必须实施 iequalityComparer generic界面中的界面.以下 代码示例显示了如何在自定义数据中实现此界面 键入并提供gethashcode并等于方法.

然后,他们显示了一个示例,其中根本不实现IEqualityComparer<T>接口,而是实现IEquatable<T>.我自己已经完成了测试,而没有实现IqualityComparer或Iquatable,并且简单地覆盖对象的平等,我发现它可以解决问题.这是样本:

class AlwaysEquals
{
    override public bool Equals(Object o)
    {
        return true;
    }
    public override int GetHashCode()
    {
        return 1;
    }
}

在这里请注意,我的班级尚无任何实施,没有i equatable,没有iequalityComparer,什么也没有.但是,当我运行此代码时:

AlwaysEquals ae1 = new AlwaysEquals();
AlwaysEquals ae2 = new AlwaysEquals();
AlwaysEquals ae3 = new AlwaysEquals();
AlwaysEquals[] Ae1 = new AlwaysEquals[] {ae3, ae2, ae3};
AlwaysEquals[] Ae2 = new AlwaysEquals[] {ae1, ae1, ae1};
Console.WriteLine(Ae1.SequenceEqual(Ae2));

..我得到True,而不是False,正如阅读文档所期望的那样.这实际上是如何工作的?

推荐答案

i Equabalable 使用词典等通用集合来确定两个对象是否相等.如果对象无法实现Iquatable,则使用对象.

为什么要实现Iquatable?它具有比对象更好的性能.因为不需要施放对象.

何时不实现i Equapable? ">一些开发人员认为,您应该只能在密封类上实施.

如果 iequalityComparer 以序列等式指定,则用来检查两个对象而不是对象的平等.以序列等式使用它的示例在此处http://msdn.microsoft.com/en-us/library/bb342073%28v=vs.110%29.aspx" aspx" http://msdn.microsoft.com/en-us/library/bb342073%28v=vs.110%29.aspx .请注意,该方法签名接受IequalityComparer.

许多收藏品,例如 dictionary 还接受iqualityComparer的构造函数

回答您的问题

如果您不提供iequalityComparer到sequenceEquals,它将使用EqualityComparer.default.

分解代码:

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
  return Enumerable.SequenceEqual<TSource>(first, second, (IEqualityComparer<TSource>) null);
}

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
  if (comparer == null)
    comparer = (IEqualityComparer<TSource>) EqualityComparer<TSource>.Default;
...

equalityComparer.default检查t类型是否实现了 system.iequatable 接口,如果是的,则返回使用该实现的EqualityComparer.否则,它将返回一个使用 object.quals.equals 和 object.gethashcode 的EqualityComparer.

本文地址:https://www.itbaoku.cn/post/1556909.html

问题描述

On this page on MSDN they describe the SequenceEqual method of the Enumerable class.

Halfway down the page it states:

If you want to compare the actual data of the objects in the sequences instead of just comparing their references, you have to implement the IEqualityComparer generic interface in your class. The following code example shows how to implement this interface in a custom data type and provide GetHashCode and Equals methods.

Then they show an example where they do not implement the IEqualityComparer<T> interface at all but instead implement IEquatable<T>. I've done the test myself without implementing either IEqualityComparer or IEquatable and simply overriding Object's Equals and I find it does the trick. Here is the sample:

class AlwaysEquals
{
    override public bool Equals(Object o)
    {
        return true;
    }
    public override int GetHashCode()
    {
        return 1;
    }
}

Note here that my class AlwaysEquals implements nothing, no IEquatable, no IEqualityComparer, nothing. However when I run this code:

AlwaysEquals ae1 = new AlwaysEquals();
AlwaysEquals ae2 = new AlwaysEquals();
AlwaysEquals ae3 = new AlwaysEquals();
AlwaysEquals[] Ae1 = new AlwaysEquals[] {ae3, ae2, ae3};
AlwaysEquals[] Ae2 = new AlwaysEquals[] {ae1, ae1, ae1};
Console.WriteLine(Ae1.SequenceEqual(Ae2));

.. I get True and not False as I would expect from reading the documentation. How does this actually work?

推荐答案

IEquatable is used by the generic collections like Dictionary to determine if two objects are equal. If the object doesn't implement IEquatable, Object.Equals method is used.

Why should you implement IEquatable? It has better performance than Object.Equals because the object doesn't need to be casted.

When to not implement IEquatable? Some developers believe that you should only implement it on sealed classes.

If IEqualityComparer is specified in SequenceEquals, it is the one used to check the equality of two objects instead of Object.Equal and it's IEquatable implementation. The example for using it in SequenceEqual is in here http://msdn.microsoft.com/en-us/library/bb342073%28v=vs.110%29.aspx. Note that the method signature accepts an IEqualityComparer.

Many collections like Dictionary also accepts IEqualityComparer in it's constructor

Answering your question

If you didn't provide an IEqualityComparer to SequenceEquals, it will use EqualityComparer.Default.

Decompiled code:

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
  return Enumerable.SequenceEqual<TSource>(first, second, (IEqualityComparer<TSource>) null);
}

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
  if (comparer == null)
    comparer = (IEqualityComparer<TSource>) EqualityComparer<TSource>.Default;
...

EqualityComparer.Default checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T. This is why your Object.Equals is called.