Question

Je suis en train de faire quelques octets [] comparaisons.

J'ai essayé == mais cela est tout comme la base Equals qui:

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

J'ai essayé d'ajouter une méthode d'extension, mais étant donné que la classe de base surchargée Égale prend les mêmes arguments, il va à la méthode de base plutôt à l'extension, est là, je peux quand même utiliser une Égale extension (wthout changer son nom. ..) ou (encore mieux) utiliser == opérateur?

Voici ce que j'ai fait au comparateur:

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;
}
Était-ce utile?

La solution

using System.Linq;

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

Autres conseils

Vous ne pouvez certainement pas faire la surcharge d'opérateur avec des méthodes d'extension. La raison pour laquelle il ne fonctionne pas pour la méthode est que si Equals toute méthode est applicable sans utiliser des méthodes d'extension, cette méthode sera choisie avant les méthodes d'extension sont même examinées.

Même si votre méthode est Enumerable.SequenceEquals « meilleur » en termes de conversion des types d'arguments aux types de paramètres formels, le compilateur préfère toujours les méthodes « normales ». Vous devrez donner votre méthode un nom différent.

Cependant, vous pouvez toujours utiliser la méthode ICollection<T>. Je ne crois pas que le court-circuit de contrôle de longueur bien (même si elle pouvait, pour les mises en œuvre) SequenceEquals. Vous pouvez toujours mettre en œuvre une version plus efficace vous bien. En effet, si vous changez simplement votre implémentation de tableau existant à appeler ou même ArrayEquals <=>, ce serait 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;
}

Notez qu'il serait tout à fait agréable de rendre générique, mais cela coûterait certainement un peu de performance que la comparaison ne pouvait être 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;
}

Je l'ai fait dans le même but:

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

mais il faut noter que les Equals () peut même revenir faux sur référence-types quand ils sont égaux (je ne l'ai pas le test, mais vous pouvez essayer avec StringBuilder). Dans mon cas particulier, je ne dispose que de simples types de valeur

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top