.net IEqualityComparer和IEquatable在Enumerable.SequenceEqual方法中的角色是什么

.net IEqualityComparer和IEquatable在Enumerable.SequenceEqual方法中的角色是什么,.net,linq,equality,.net,Linq,Equality,在上的本页中,他们描述了可枚举类的SequenceEqual方法 在这一页的一半,它指出: 如果要比较序列中对象的实际数据 您必须实现 类中的IEqualityComparer通用接口。以下 代码示例显示了如何在自定义数据源中实现此接口 键入并提供GetHashCode和Equals方法 然后,他们展示了一个示例,其中他们根本没有实现IEqualityComparer接口,而是实现IEquatable。我自己做了这个测试,没有实现IEqualityComparer或IEquatable,只是简单

在上的本页中,他们描述了
可枚举类的
SequenceEqual
方法

在这一页的一半,它指出:

如果要比较序列中对象的实际数据 您必须实现 类中的IEqualityComparer通用接口。以下 代码示例显示了如何在自定义数据源中实现此接口 键入并提供GetHashCode和Equals方法

然后,他们展示了一个示例,其中他们根本没有实现
IEqualityComparer
接口,而是实现
IEquatable
。我自己做了这个测试,没有实现IEqualityComparer或IEquatable,只是简单地覆盖了对象的Equals,我发现它做到了。以下是示例:

class AlwaysEquals
{
    override public bool Equals(Object o)
    {
        return true;
    }
    public override int GetHashCode()
    {
        return 1;
    }
}
请注意,我的类始终没有实现任何东西,没有IEquatable,没有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
,正如我在阅读文档时所期望的那样。这实际上是如何工作的?

IEquatable被字典之类的通用集合用来确定两个对象是否相等。如果对象未实现IEquatable,则使用object.Equals方法

为什么要实施IEquatable?它比Object.Equals具有更好的性能,因为对象不需要强制转换

何时不实施IEquatable

如果SequenceEquals中指定了IEqualityComparer,则它是用来检查两个对象是否相等的,而不是Object.Equal及其IEquatable实现。在SequenceEqual中使用它的示例如下。请注意,方法签名接受IEqualityComparer

许多集合(如)也在其构造函数中接受IEqualityComparer

回答您的问题

如果您没有为SequenceEquals提供IEqualityComparer,它将使用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;
...
publicstaticboolsequenceequal(第一个是IEnumerable,第二个是IEnumerable)
{
返回可枚举的.SequenceEqual(第一,第二,(IEqualityComparer)null);
}
公共静态布尔序列相等(此IEnumerable第一,IEnumerable第二,IEqualityComparer比较器)
{
if(比较器==null)
comparer=(IEqualityComparer)EqualityComparer.Default;
...

EqualityComparer.Default检查类型T是否实现System.IEquatable接口,如果是,则返回使用该实现的EqualityComparer。否则,它返回使用T提供的Object.Equals和Object.GetHashCode重写的EqualityComparer。这就是调用Object.Equals的原因。

IEquatable被字典等通用集合用于确定两个对象是否相等。如果该对象未实现IEquatable,则使用object.Equals方法

为什么要实现IEquatable?它比Object.Equals性能更好,因为对象不需要强制转换

何时不实施IEquatable

如果在SequenceEquals中指定了IEqualityComparer,则它是用于检查两个对象的相等性而不是Object.Equal及其IEquatable实现。在SequenceEqual中使用它的示例如下。请注意,方法签名接受IEqualityComparer

许多集合(如)也在其构造函数中接受IEqualityComparer

回答您的问题

如果您没有为SequenceEquals提供IEqualityComparer,它将使用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;
...
publicstaticboolsequenceequal(第一个是IEnumerable,第二个是IEnumerable)
{
返回可枚举的.SequenceEqual(第一,第二,(IEqualityComparer)null);
}
公共静态布尔序列相等(此IEnumerable第一,IEnumerable第二,IEqualityComparer比较器)
{
if(比较器==null)
comparer=(IEqualityComparer)EqualityComparer.Default;
...

EqualityComparer.Default检查类型T是否实现System.IEquatable接口,如果是,则返回使用该实现的EqualityComparer。否则,它返回使用T提供的Object.Equals和Object.GetHashCode重写的EqualityComparer。这就是调用Object.Equals的原因。

这就解释了发生了什么尽管我不得不说模式不明显!好吧,这解释了发生了什么尽管我不得不说模式不明显!