2011-01-04 26 views
5

Sólo tengo que hacer una simple comparación es decirComparar objetos?

byte[] keya = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1"); 
byte[] keyb = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1"); 
Console.WriteLine(keya == keyb); 

pero el resultado es falso, y su código hash es también diferente, me estoy perdiendo algo aquí?

¡Gracias de antemano!

+2

Si puede usar LINQ, puede hacer 'keya.SequenceEqual (keyb)'. – Ani

+0

Desafortunadamente eso no está disponible en mono. – Ali

+1

¿No es este un duplicado de [Comparar dos objetos de matriz .Net (matrices de bytes)] (http://stackoverflow.com/q/486749/15639)? – MarkJ

Respuesta

11

No creo que haya nada en el marco que le proporcione igualdad de matrices en la forma que usted desearía. Sin embargo, no es demasiado difícil escribir su propia implementación de IEqualityComparer<T> para arreglos. Por ejemplo (compilado pero no probado):

public static class ArrayEqualityComparer 
{ 
    public static IEqualityComparer<T[]> Create<T>(
     IEqualityComparer<T> comparer) 
    { 
     return new ArrayEqualityComparer<T>(comparer); 
    } 
} 

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]> 
{ 
    private static readonly IEqualityComparer<T[]> defaultInstance = new 
     ArrayEqualityComparer<T>(); 

    public static IEqualityComparer<T[]> Default 
    { 
     get { return defaultInstance; } 
    } 

    private readonly IEqualityComparer<T> elementComparer; 

    public ArrayEqualityComparer() : this(EqualityComparer<T>.Default) 
    { 
    } 

    public ArrayEqualityComparer(IEqualityComparer<T> elementComparer) 
    { 
     this.elementComparer = elementComparer;   
    } 

    public bool Equals(T[] x, T[] y) 
    { 
     if (x == y) 
     { 
      return true; 
     } 
     if (x == null || y == null) 
     { 
      return false; 
     } 
     if (x.Length != y.Length) 
     { 
      return false; 
     } 
     for (int i = 0; i < x.Length; i++) 
     { 
      if (!elementComparer.Equals(x[i], y[i])) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    public int GetHashCode(T[] array) 
    { 
     if (array == null) 
     { 
      return 0; 
     } 
     int hash = 23; 
     foreach (T item in array) 
     { 
      hash = hash * 31 + elementComparer.GetHashCode(item); 
     } 
     return hash; 
    } 
} 

(Tenga en cuenta que esto supone actualmente que elementComparer hará frente a los valores nulos, tanto para GetHashCode y Equals La interfaz no garantiza que, aunque los comparadores de igualdad predeterminado realidad lo hacen. . manejarlo se podría modificar el código anterior para ser más robusto, por supuesto ... es que no tengo tiempo ahora)

Uso:.

IEqualityComparer<byte[]> x = ArrayEqualityComparer<byte>.Default; 
bool equal = x.Equals(bytes1, bytes2); 

IEqualityComparer<string[]> y = 
    ArrayEqualityComparer.Create(StringComparer.OrdinalIgnoreCase); 
bool whatever = x.Equals(new[][] { "X", "Y" }, new[] { "x", "y" }); 
+0

@Jon Estoy realmente sorprendido de que no estés comentando sobre el uso de System.Text.Encoding.ASCII.GetBytes –

+1

@Conrad: supongo que esa fue la forma más simple en que el OP pudo pensar para crear dos " "matrices de bytes iguales". –

+0

@Jon ok, es justo –

4

keya y keyb son dos objetos completamente separados que simplemente contienen los mismos bytes.

Si quiere comparar para ver si dos cadenas tienen los mismos caracteres, quizás debería mirar métodos como String.Equals?

+2

Sí, o recorra las matrices y compare cada par de bytes. –

+0

En realidad, no quiero iterar la colección de claves que son de byte [] tipo de datos porque ya sé la clave y cuando obtengo los bytes de la cadena, entonces no me devolvió el objeto corresponde a esa clave, pero cuando uso la referencia de la clave de la iteración que encontré el objeto, ¿por qué es así? – Ali

+0

@ Ali: ¿Parece que está utilizando estos arreglos de bytes como claves en una colección? En primer lugar, si se trata de representaciones de cadenas, sería mejor utilizar las mismas cadenas como claves, de lo contrario, puede escribir su propio comparador de igualdad e indicarle a la colección que lo use en lugar del predeterminado. –

1

Esta extensión genérica debe hacer el truco:

public static class ArrayExtensions 
{ 
    public static bool ElementsEqual<T>(this T[] left, T[] right) 
     where T : IEquatable<T> 
    { 
     if (left == null || right == null) 
     { 
      return !(left == null^right == null); 
     } 
     else if (left.Length != right.Length) 
     { 
      return false; 
     } 

     for (int i = 0; i < left.Length; i++) 
     { 
      if (!left[i].Equals(right[i])) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 
} 
1

Las matrices son los tipos de referencia lo que las pruebas para la igualdad comprueba si los indicadores son los mismos. Ellos no están.

Si quiere comparar los elementos y no las matrices en sí, puede import System.Linq y usar keya.SequenceEqual(keyb).

+0

desafortunadamente eso no está disponible en mono, que es mi entorno de desarrollo. – Ali

+0

@ Ali: Ah, entonces tienes que comparar cada elemento como las otras respuestas aquí. –

+0

@ Ali: Creo que Mono ha apoyado LINQ to Objects por bastante tiempo. –

Cuestiones relacionadas