2012-09-30 6 views
7

Ich habe 2 Arrays:Vergleich Arrays Inhalt, Differenz von SequenceEqual und StructuralComparisons.StructuralEqualityComparer

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

Ich muss überprüfen, ob sie gleich sind (nicht durch ref)

Was ist der Unterschied zwischen dem Schreiben ist:

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

vs

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

beide liefert True ..

Wann sollte ich jedes verwenden?

+0

IStructuralEquatable bietet eine Funktion zur Überprüfung der Gleichheit und Vergleich zweier Arrays. –

+2

@leppie Ich war wiering, warum Sie die .net4-Tag entfernt :-) IStructuralEquatable existiert nur in 4. und das ist, warum ich es dort :-) –

+0

@RoyiNamir: Nachdem ich es entfernt habe ich mich gefragt, das gleiche, dann habe ich faul und vergaß es; p – leppie

Antwort

1

Die Implementierung von SequenceEqual ist eine Art ähnlich ::

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; 

Dieser Standard SequenceEqual Methode verwenden Sie den Standard EqualityComparer<int>.Default für int die Wertgleichheit ist.

ArrayIStructuralEquatable mit Equal Methode implementieren:

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

Die IEqualityComparer von Eingabeparameter verwendet wird, hier Eingabe StructruralEqualityComparer aber int nicht IStructruralEquatable nicht implementiert, so dass es Standardvergleich für int verwendet, welchen Wert Gleichheit ist.

Aber unnötig zu Eingang StructruralEqualityComparer weil int nicht strukturell bedingt ist, sollten Sie nur verwenden:

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

Es funktioniert immer noch.Sie sollten StructruralEqualityComparer verwenden, wenn das Element in Array structrural

So ist die Implementierung für beide zusammenzufassen, ist eine Art von der gleichen, beide iterieren zwei Array basiert auf Wertgleichheit von int zum Vergleich.

Ich würde die LINQ-Version bevorzugen, da es besser lesbar ist.

-1

Ich denke System.Linq ist dein Freund:

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

Danke, aber ich fragte, was ist der Unterschied. Und wann sollte ich welche verwenden ... :-) –

0

Die Linq-Version ist die flexibelste, kann es zwei enumerables vergleichen.
Die StructuralComparisons.StructuralEqualityComparer-Version erfordert, dass die beiden Auflistungen die IStructuralEquatable-Schnittstelle unterstützen können. Aber ich würde erwarten, dass das letztere schneller ist, wenn die beiden Listen ungleiche Längen haben.

1

Die Standardgleichheitsprüfungen in .NET verwenden EqualityComparer.Default für Vergleiche. Für Beispielwörterbücher oder die SequenceEqual-Methode, die Sie dort geschrieben haben, wird standardmäßig EqualityComparer.Default verwendet. Und dieser Vergleicher verwendet entweder Equals (Objekt) -Methode oder Equals (T) -Methode bei Vorhandensein einer IEquatable-Schnittstellenimplementierung.

Aber Sie können anderen Vergleichern wie StructuralComparisons.StructuralEqualityComparer immer Wörterbücher oder Methoden wie SequenceEqual geben.

Der Hauptunterschied zwischen zwei Methoden ist also die Methode der Gleichheitsprüfung, die sie verwenden. SequenceEqual verwendet die IEquatable-Schnittstellenmethode für Prüfungen und StructuralComparisons.StructuralEqualityComparer verwendet die IStructuralEquatable-Schnittstellenmethode für Prüfungen. Daher benötigen die Standardgleichheitsprüfungen zwei der verglichenen Elemente, die denselben Typ haben, aber StructuralEqualityComparer erfordert nicht, dass sie vom gleichen Typ sind. Wie der Name schon sagt, soll es Inhalte vergleichen.

1

Ich hatte gerade eine verwandte Frage und sah, dass diese Frage nie richtig beantwortet wurde. Es gibt einen Unterschied zwischen Struktur und Sequenz - der erste Vergleich ist tief und der zweite nicht.

Dieser einfache Code demonstriert und produziert TrueFalse:

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

Der Name "Sequenz", schlägt ein dimensionalism so der Name Wahl angemessen ist.

Verwandte Themen