Pergunta

Estou fazendo algumas byte [] comparações.

Eu tentei == mas isso é apenas como a base é igual, que:

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

Eu tentei adicionar um método de extensão, mas desde que a classe base sobrecarregado Igual leva os mesmos argumentos, ele vai para o método base, em vez da extensão, se houver qualquer maneira eu posso usar um é igual a extensão (wthout mudá-la de nome. ..) ou (melhor ainda) uso == operador?

Aqui está o que eu realmente tenho 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;
}
Foi útil?

Solução

using System.Linq;

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

Outras dicas

Você certamente não pode fazer sobrecarga de operadores com os métodos de extensão. O motivo ele não funciona para o método Equals é que se qualquer método é aplicável sem o uso de métodos de extensão, esse método será escolhido antes de métodos de extensão são ainda examinadas.

Mesmo que o seu método Equals é "melhor" em termos de converter os tipos de argumentos para os tipos de parâmetros formais, o compilador prefere sempre métodos "normais". Você vai ter que dar o seu método um nome diferente.

No entanto, você sempre pode usar o método Enumerable.SequenceEquals. Eu não acredito que um curto-circuito a verificação de comprimento embora (mesmo que pudesse, para implementações ICollection<T>). Você sempre pode implementar uma versão mais eficiente-se embora. De fato, se você acabou de mudar a sua implementação matriz existente para ser chamado SequenceEquals ou mesmo ArrayEquals, que seria ótimo:

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

Note que seria muito bom para torná-lo genérico, mas que certamente custar um pouco de desempenho como a comparação não pode ser embutido:

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

Eu fiz isso para o mesmo fim:

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

Mas note que os .Equals () pode até retornar falso em referência tipos quando eles são iguais (I não fez o teste, mas você pode tentar com StringBuilder). No meu caso particular só tenho simples de valor tipos

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top