【问题标题】:IEqualityComparer for SequenceEqualSequenceEqual 的 IEqualityComparer
【发布时间】:2013-02-03 18:25:56
【问题描述】:

在 C# 中,是否有 IEqualityComparer<IEnumerable> 使用 SequenceEqual 方法来确定相等性?

【问题讨论】:

  • 它将用于实现GetHashCode
  • 不完全按照您的要求,但如果您将自己限制在T[](不是一般的IEnumerable<T>),您可以使用StructuralComparisons.StructuralEqualityComparer.Equals(arr1, arr2)StructuralComparisons.StructuralEqualityComparer.GetHashCode(arr)。不是 BCL 的最佳解决方案,也不是那么类型安全(您可以将其包装在从 EqualityComparer<T[]> 派生的您自己的类中,以确保它仅在 T[] 上使用),但它存在。

标签: c# .net linq iequalitycomparer


【解决方案1】:

.NET Framework 中没有这样的比较器,但您可以创建一个:

public class IEnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        return Object.ReferenceEquals(x, y) || (x != null && y != null && x.SequenceEqual(y));
    }

    public int GetHashCode(IEnumerable<T> obj)
    {
        // Will not throw an OverflowException
        unchecked
        {
            return obj.Where(e => e != null).Select(e => e.GetHashCode()).Aggregate(17, (a, b) => 23 * a + b);
        }
    }
}

在上面的代码中,我遍历了GetHashCode 中集合的所有项目。我不知道这是否是最明智的解决方案,但这是在内部 HashSetEqualityComparer 中完成的。

【讨论】:

  • 仅供参考,HashSetEqualityComparer 中的当前哈希值不是您在这里所拥有的。反正这不是你想要的。它不比较 sequence 而是比较 set - 它的哈希故意在具有不同顺序的相同项目的序列之间发生冲突。你这里的代码很好。
  • 很好的实现,未选中的是否最好只包含可能溢出的实际计算?
  • 请注意,根据您打算如何处理该事物,将哈希码简单地实现为int GetHashCode(IEnumnerable&lt;T&gt; object) =&gt; 0; 可能是合理的
【解决方案2】:

基于Cédric Bignon's answer创建了一个NuGet包:

组装包: https://www.nuget.org/packages/OBeautifulCode.Collection/

仅代码文件包:https://www.nuget.org/packages/OBeautifulCode.Collection.Recipes.EnumerableEqualityComparer/

var myEqualityComparer = new EnumerableEqualityComparer<string>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多