Domanda

sto facendo alcuni byte [] paragoni.

Ho provato == ma questo è proprio come la base Equals, che:

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

Ho provato ad aggiungere un metodo di estensione, ma dal momento che la classe di base sovraccarico Equals prende gli stessi argomenti, si va al metodo di base piuttosto per l'estensione, c'è qualche cosa che posso usare di uguale estensione (wthout cambiando il suo nome. ..) o (ancora meglio) utilizzare == operatore?

Ecco quello che ho effettivamente al Confronto:

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;
}
È stato utile?

Soluzione

using System.Linq;

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

Altri suggerimenti

Non si può certo fare l'overloading degli operatori con i metodi di estensione. Il motivo per cui non funziona per il metodo Equals è che se qualsiasi metodo è applicabile senza utilizzare metodi di estensione, sarà scelto tale metodo prima metodi di estensione sono anche esaminati.

Anche se il metodo di Enumerable.SequenceEquals è "migliore" in termini di conversione dei tipi di argomenti per i tipi di parametri formali, il compilatore preferisce sempre i metodi "normali". Dovrete dare il metodo di un nome diverso.

Tuttavia, si può sempre utilizzare il metodo ICollection<T>. Non credo che cortocircuita il controllo di lunghezza anche se (anche se potrebbe, ad SequenceEquals implementazioni). Si può sempre implementare una versione più efficiente da soli però. In effetti, se basta cambiare l'implementazione array esistente per essere chiamato ArrayEquals o addirittura <=>, che sarebbe bene:

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

Si noti che sarebbe molto bello per rendere più generica, ma che sarebbe certamente costare un po 'di performance come il confronto non poteva essere 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;
}

L'ho fatto per lo stesso scopo:

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

meno di notare che le .equals () può anche return false su di riferimento-tipi, quando sono uguali (non ho fatto il test, ma si può provare con StringBuilder). Nel mio caso particolare, ho solo semplice valore-tipo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top