比较数组内容,SequenceEqual和StructuralComparisons.StructuralEqualityComparer的差异

时间:2012-09-30 08:16:43

标签: c# .net .net-4.0

我有2个阵列:

        int[] arr1 = new int[] { 1, 2, 3 };
        int[] arr2 = new int[] { 1, 2, 3 };

我需要检查它们是否相等(不是参考)

写作之间有什么区别:

        Console.WriteLine(arr1.SequenceEqual(arr2)); //true

VS

        IStructuralEquatable eqArray1 = arr1;
        Console.WriteLine(eqArray1.Equals(arr2, StructuralComparisons.StructuralEqualityComparer));  //true

都返回True ..

我应该何时使用?

5 个答案:

答案 0 :(得分:2)

我刚才有一个相关的问题,看到这个问题从来没有得到真正的回答。结构和序列之间存在差异 - 第一个比较深,第二个比较不。

这个简单的代码演示并生成True False

int[][] ints1 = { new int[] { 3, 4 } };
int[][] ints2 = { new int[] { 3, 4 } };
Console.WriteLine(StructuralComparisons.
                          StructuralEqualityComparer.Equals(ints1, ints2));
Console.WriteLine(ints1.SequenceEqual(ints2));

名称“序列”表示一维主义,因此名称选择是恰当的。

答案 1 :(得分:1)

.NET中的标准相等性检查使用EqualityComparer.Default进行比较。例如,您编写的字典或SequenceEqual方法默认使用EqualityComparer.Default。并且该比较器在IEquatable接口实现的情况下使用Equals(object)方法或Equals(T)方法。

但是你总是可以给像StructuralComparisons.StructuralEqualityComparer这样的其他比较器提供字典或方法,比如SequenceEqual。

因此,两种方法的主要区别在于它们使用的等式检查方法。 SequenceEqual使用IEquatable接口方法进行检查,而StructuralComparisons.StructuralEqualityComparer使用IStructuralEquatable接口方法进行检查。因此,默认的相等检查需要两个比较的项目是相同的类型,但StructuralEqualityComparer不要求它们是相同的类型。顾名思义它应该比较内容。

答案 2 :(得分:1)

SequenceEqual的实现有点类似::

using (IEnumerator<TSource> enumerator1 = first.GetEnumerator())
using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())
{
    while (enumerator1.MoveNext())
    {
        if (!enumerator2.MoveNext() || !comparer.Equals(enumerator1.Current, enumerator2.Current))
        {
            return false;
        }
    }

    if (enumerator2.MoveNext())
    {
        return false;
    }
}

return true;

此默认SequenceEqual方法使用EqualityComparer<int>.Default的默认int,这是值相等。

Array使用IStructuralEquatable方法实施Equal

bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
    if (other == null) return false;

    if (!object.ReferenceEquals(this, other))
    {
        Array array = other as Array;
        if ((array == null) || (array.Length != this.Length))
        {
            return false;
        }
        for (int i = 0; i < array.Length; i++)
        {
            object x = this.GetValue(i);
            object y = array.GetValue(i);

            if (!comparer.Equals(x, y))
            {
                return false;
            }
        }
    }

    return true;
}

使用输入参数中的IEqualityComparer,此处输入StructruralEqualityComparerint未实现IStructruralEquatable,因此它使用int的默认比较器这是价值平等。

但是,由于StructruralEqualityComparer不是结构性的,因此无需输入int,您应该使用:

(arr1 as IStructuralEquatable).Equals(arr2, EqualityComparer<int>.Default);

它仍然有效。如果数组中的项目是 structrural

,则应使用StructruralEqualityComparer

总而言之,两者的实现是相同的,都基于int的值相等来迭代两个数组以进行比较。

我更喜欢LINQ版本,因为它更具可读性。

答案 3 :(得分:0)

linq版本最灵活,它可以比较两个枚举 StructuralComparisons.StructuralEqualityComparer版本要求两个集合可以支持IStructuralEquatable接口。但如果两个列表的长度不均匀,我希望后者更快。

答案 4 :(得分:-1)

我认为System.Linq是你的朋友:

bool isEqual = Enumerable.SequenceEqual(array1, array2);