Pregunta

Estoy haciendo algunas comparaciones byte [].

He intentado == pero esto es igual que la base es igual, que:

byte[] a = {1,2,3};
byte[] b = {1,2,3};
bool equals = a == b; //false
equals = a.Equals(b); //false

He intentado añadir un método de extensión, pero dado que la clase base sobrecargada es igual a toma los mismos argumentos, no hace falta que el método de base en lugar de la extensión, de todos modos hay que puedo utilizar un signo de igual extensión (wthout cambiando su nombre. ..) o (mejor aún) utilizar el operador ==?

Esto es lo que realmente tiene que comparar:

public static bool ContentEquals(this byte[] array, byte[] bytes)
{
    if (array == null || bytes == null) throw new ArgumentNullException();
    if( array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)
        if (array[i] != bytes[i]) return false;

    return true;
}
¿Fue útil?

Solución

using System.Linq;

byte[] a = {1,2,3}; 
byte[] b = {1,2,3}; 
bool same = a.SequenceEqual(b);

Otros consejos

Por supuesto que no se puede hacer la sobrecarga de operadores con los métodos de extensión. La razón por la que no funciona para el método Equals es que si cualquier método es aplicable sin necesidad de utilizar métodos de extensión, que el método será elegido antes de los métodos de extensión son incluso examinaron.

A pesar de que su método de Enumerable.SequenceEquals es "mejor" en términos de la conversión de los tipos de argumentos a los tipos de parámetros formales, el compilador siempre prefiere métodos "normales". Vas a tener que dar a su método un nombre diferente.

Sin embargo, siempre se puede utilizar el método de ICollection<T>. No creo que cortocircuita la verificación de longitud, aunque (a pesar de que podría, por SequenceEquals implementaciones). Siempre se puede poner en práctica una versión más eficiente a sí mismo sin embargo. De hecho, si sólo cambia su aplicación matriz existente a llamarse ArrayEquals o incluso <=>, que estaría bien:

public static bool ArrayEquals(this byte[] array, byte[] bytes)
{
    // I'd personally use braces in all of this, but it's your call
    if (array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)     
        if (array[i] != bytes[i]) return false;

    return true;
}

Tenga en cuenta que sería muy agradable para que sea genérico, pero eso ciertamente costar un poco de rendimiento que la comparación no puede ser inline:

public static bool ArrayEquals<T>(this T[] first, T[] second)
{
    // Reference equality and nullity checks for safety and efficiency
    if (first == second)
    {
        return true;
    }
    if (first == null || second == null)
    {
        return false;
    }
    if (first.Length != second.Length)
    {
        return false;
    }        
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < first.Length; i++)
    {
        if (!comparer.Equals(first[i], second[i]))
        {
             return false;
        }
    }
    return true;
}

Lo hice con el mismo propósito:

static class Global
{
    public static bool ArraysAreEqual(Array arr1, Array arr2)
    {
        if (arr1.Length != arr2.Length)
            return false;

        System.Collections.IEnumerator e1 = arr1.GetEnumerator();
        System.Collections.IEnumerator e2 = arr2.GetEnumerator();

        while(e1.MoveNext() && e2.MoveNext())
        {
            if(!e1.Current.Equals(e2.Current))
                return false;
        }
        return true;
    }
}

Pero Tenga en cuenta que los .equals () puede incluso volver falsa en referencia tipos cuando son iguales (no lo hice la prueba, pero se puede tratar con StringBuilder). En mi caso particular tengo de valor sólo los tipos simples

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top