1

MSDN的这个页面上,他们描述了类的SequenceEqual方法Enumerable

它在页面的中途说:

如果你想比较序列中对象的实际数据而不是仅仅比较它们的引用,你必须在你的类中实现 IEqualityComparer 通用接口。以下代码示例展示了如何在自定义数据类型中实现此接口并提供 GetHashCode 和 Equals 方法。

然后他们展示了一个示例,他们根本不实现IEqualityComparer<T>接口,而是实现IEquatable<T>. 我自己完成了测试,没有实现 IEqualityComparer 或 IEquatable,只是简单地覆盖了 Object 的 Equals,我发现它可以解决问题。这是示例:

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

请注意,我的类 AlwaysEquals 什么都没有实现,没有 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像阅读文档所期望的那样。这实际上是如何工作的?

4

1 回答 1

5

IEquatable被 Dictionary 等通用集合用于确定两个对象是否相等。如果对象没有实现 IEquatable,则使用 Object.Equals 方法。

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

什么时候不实施 IEquatable? 一些开发人员认为您应该只在密封类上实现它

如果在 SequenceEquals 中指定了IEqualityComparer,则它是用于检查两个对象是否相等的对象,而不是 Object.Equal,它是 IEquatable 实现。在 SequenceEqual 中使用它的示例在这里http://msdn.microsoft.com/en-us/library/bb342073%28v=vs.110%29.aspx。请注意,方法签名接受 IEqualityComparer。

许多像Dictionary这样的集合在它的构造函数中也接受 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;
...

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

于 2013-10-30T02:55:33.750 回答