7

我有 2 个数组:

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

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

write 和有什么不一样:

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

对比

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

两者都返回 True ..

我应该什么时候使用每个?

4

5 回答 5

2

The implementation of SequenceEqual is kind of similar::

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;

This default SequenceEqual method use default EqualityComparer<int>.Default for int which is value equality.

Array implement IStructuralEquatable with Equal method:

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;
}

The IEqualityComparer from input parameter is used, in here you input StructruralEqualityComparer but int does not implement IStructruralEquatable, so it uses default comparer for int which is value equality.

But, needless to input StructruralEqualityComparer because int is not structural, you should just use:

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

It still works. You should use StructruralEqualityComparer if item in array is structrural

So to sum up, the implementation for both is kind of the same, both iterate two array based on value equality of int to make comparison.

I would prefer the LINQ verson since it is more readable.

于 2012-09-30T14:05:25.283 回答
2

I just had a related question and saw that this question was never actually answered properly. There is a difference between the structural and the sequence - the first comparison is deep and the second one is not.

This simple code demonstrates and produces 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));

The name "sequence" suggests one-dimensionalism so the name choice is appropriate.

于 2013-10-30T01:20:40.923 回答
1

Standard equality checks in .NET uses EqualityComparer.Default for comparisons. For example dictionaries or SequenceEqual method you have written there uses EqualityComparer.Default by default. And that comparer either uses Equals(object) method or Equals(T) method in presence of IEquatable interface implementation.

But you can always give other comparers like StructuralComparisons.StructuralEqualityComparer to dictionaries or methods such as SequenceEqual.

So, the main difference between two methods is the equality check method they use. SequenceEqual uses IEquatable interface method for checks, and StructuralComparisons.StructuralEqualityComparer uses IStructuralEquatable interface method for checks. And as a result, default equality checks need two of the compared items to be the same type but StructuralEqualityComparer doesn't require them to be same type. As the name suggests it is supposed to compare contents.

于 2012-09-30T09:02:41.703 回答
0

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

于 2012-09-30T08:53:57.567 回答
-1

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

bool isEqual = Enumerable.SequenceEqual(array1, array2);
于 2012-09-30T08:23:48.583 回答