7

私は2つの配列を持っています:

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

それらが等しいかどうかを確認する必要があります(参照ではありません)

書くことの違いは何ですか:

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

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

どちらもTrueを返します..

それぞれをいつ使用する必要がありますか?

4

5 に答える 5

2

の実装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

ArrayIStructuralEquatableメソッドで実装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;
}

IEqualityComparerfrom 入力パラメーターが使用されます。ここでは、入力しますが実装StructruralEqualityComparerintないため、値が等しいIStructruralEquatableデフォルトの比較子が使用されます。int

StructruralEqualityComparerただし、構造的ではないため、入力する必要intはありません。次を使用する必要があります。

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

それはまだ動作します。StructruralEqualityComparer配列内の項目が構造的である場合に使用する必要があります

要約すると、両方の実装は同じようなもので、どちらも値の等価性に基づいて 2 つの配列を反復intして比較します。

より読みやすいため、LINQバージョンをお勧めします。

于 2012-09-30T14:05:25.283 に答える
2

関連する質問がありましたが、この質問が実際には適切に回答されていないことがわかりました。構造とシーケンスには違いがあります。最初の比較は深く、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 次元主義を示唆しているため、この名前の選択は適切です。

于 2013-10-30T01:20:40.923 に答える
1

.NET の標準の等価性チェックでは、比較に EqualityComparer.Default が使用されます。たとえば、そこに記述した辞書または SequenceEqual メソッドは、デフォルトで EqualityComparer.Default を使用します。そして、その比較子は、IEquatable インターフェイス実装の存在下で、Equals(object) メソッドまたは Equals(T) メソッドのいずれかを使用します。

ただし、StructuralComparisons.StructuralEqualityComparer などの他の比較子を、SequenceEqual などの辞書やメソッドにいつでも与えることができます。

したがって、2 つの方法の主な違いは、使用する等価性チェック方法です。SequenceEqual はチェックに IEquatable インターフェイス メソッドを使用し、StructuralComparisons.StructuralEqualityComparer はチェックに IStructuralEquatable インターフェイス メソッドを使用します。その結果、デフォルトの等価性チェックでは、比較される項目のうち 2 つが同じ型である必要がありますが、StructuralEqualityComparer ではそれらが同じ型である必要はありません。その名の通り中身を比較することになっています。

于 2012-09-30T09:02:41.703 に答える
0

linq バージョンは最も柔軟で、2 つの列挙型を比較できます。
StructuralComparisons.StructuralEqualityComparer バージョンでは、2 つのコレクションが IStructuralEquatable インターフェイスをサポートできる必要があります。しかし、2 つのリストの長さが等しくない場合は、後者の方が速いと思います。

于 2012-09-30T08:53:57.567 に答える
-1

System.Linq はあなたの友達だと思います:

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