2012-09-30 16 views
7

tengo 2 matrices:comparar el contenido de las matrices, diferencia de SequenceEqual y StructuralComparisons.StructuralEqualityComparer

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

tengo que comprobar si son iguales (no por ref)

¿Cuál es la diferencia entre la escritura:

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

vs

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

ambos devuelven True ..

¿Cuándo debo usar cada uno?

+0

IStructuralEquatable proporciona la función para comprobar la igualdad y la comparación de dos matrices. –

+2

@leppie Me preguntaba por qué eliminaste la etiqueta .net4 :-) IStructuralEquatable existe solo en 4. y es por eso que lo puse allí :-) –

+0

@RoyiNamir: Después de eliminarlo me preguntaba lo mismo, luego obtuve perezoso y se olvidó de él; p – leppie

Respuesta

1

La implementación de SequenceEqual es un poco 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; 

Este defecto SequenceEqual utilice el método por defecto para EqualityComparer<int>.Defaultint que es la igualdad de valor.

Array implemento IStructuralEquatable con Equal método:

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

El IEqualityComparer del parámetro de entrada se utiliza, aquí usted introduce StructruralEqualityComparer pero int no implementa IStructruralEquatable, por lo que utiliza comparador predeterminado para int que es la igualdad de valor.

embargo, no hace falta entrada StructruralEqualityComparer porque int no es estructural, sólo debe usar:

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

Todavía funciona.Debe utilizar StructruralEqualityComparer si el artículo en el array es structrural

Para resumir, la implementación de ambos es el mismo tipo de, tanto iterar matriz de dos basado en el valor de la igualdad int para hacer la comparación.

Preferiría la verson LINQ ya que es más legible.

-1

creo System.Linq es su amigo:

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

Gracias, pero le pregunté cuál es la diferencia. Y cuando debería usar qué ... :-) –

0

La versión de LINQ es el más flexible, se puede comparar dos enumerables.
La versión StructuralComparisons.StructuralEqualityComparer requiere que las dos colecciones puedan admitir la interfaz IStructuralEquatable. Pero esperaría que el último sea más rápido si las dos listas son de longitud desigual.

1

Las verificaciones de igualdad estándar en .NET utilizan EqualityComparer.Default para las comparaciones. Por ejemplo, los diccionarios o el método SequenceEqual que ha escrito allí usa EqualityComparer.Default de forma predeterminada. Y ese comparador utiliza el método Igual (objeto) o el método Igual (T) en presencia de la implementación de la interfaz IEquatable.

Pero siempre puedes dar otros comparadores como StructuralComparisons.StructuralEqualityComparer a diccionarios o métodos como SequenceEqual.

Por lo tanto, la principal diferencia entre dos métodos es el método de verificación de igualdad que utilizan. SequenceEqual utiliza el método de interfaz IEquatable para las comprobaciones, y StructuralComparisons.StructuralEqualityComparer utiliza el método de interfaz IStructuralEquatable para las comprobaciones. Y como resultado, las verificaciones de igualdad predeterminadas necesitan que dos de los elementos comparados sean del mismo tipo, pero StructuralEqualityComparer no requiere que sean del mismo tipo. Como su nombre indica, se supone que debe comparar los contenidos.

1

Acabo de tener una pregunta relacionada y vi que esta pregunta nunca fue respondida correctamente. Hay una diferencia entre la secuencia estructural y la primera: la primera es profunda y la segunda no.

Este código simple Demuestra y produce 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)); 

El nombre "secuencia" sugiere un dimensionalism lo que la elección nombre es apropiado.

Cuestiones relacionadas