63 votes

Comparaison des tableaux en C #

J'essaye de comparer deux tableaux l'un avec l'autre. J'ai essayé ce code et j'ai eu les erreurs suivantes

 static bool ArraysEqual(Array a1, Array a2)
{
    if (a1 == a2)
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    IList list1 = a1, list2 = a2; //error CS0305: Using the generic type 'System.Collections.Generic.IList<T>' requires '1' type arguments
    for (int i = 0; i < a1.Length; i++)
    {
        if (!Object.Equals(list1[i], list2[i])) //error CS0021: Cannot apply indexing with [] to an expression of type 'IList'(x2)
            return false;
    }
    return true;
}
 

Pourquoi ai-je cette erreur? Je suis allé pour une solution low tech et cela a bien fonctionné, mais je dois le copier / coller plusieurs fois pour chaque type.

 static bool ArraysEqual(byte[] a1, byte[] a2)
{
    if (a1 == a2)
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    for (int i = 0; i < a1.Length; i++)
    {
        if (a1[i] != a2[i])
            return false;
    }
    return true;
}
 

163voto

Noldorin Points 67794

À condition que vous ayez LINQ disponible et que vous ne vous préoccupiez pas trop des performances, la chose la plus simple est la suivante:

 var arraysAreEqual = Enumerable.SequenceEqual(a1, a2);
 

En fait, il vaut probablement la peine de vérifier avec Reflector ou ILSpy ce que font réellement les méthodes SequenceEqual , car elles peuvent de toute façon être optimisées pour le cas particulier des valeurs de tableau!

74voto

Marc Gravell Points 482669

"Pourquoi est-ce que je reçois cette erreur?" - probablement, vous n'avez pas " using System.Collections; " en haut du fichier - seulement " using System.Collections.Generic; " - cependant, les génériques sont probablement plus sûrs - voir ci-dessous:

 static bool ArraysEqual<T>(T[] a1, T[] a2)
{
    if (ReferenceEquals(a1,a2))
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < a1.Length; i++)
    {
        if (!comparer.Equals(a1[i], a2[i])) return false;
    }
    return true;
}
 

7voto

Valentin Kuzub Points 4349

Recommander SequenceEqual est ok, mais la pensée qu'il pourrait être plus rapide que d'habitude for(;;) la boucle est trop naïf.

Ici est l'expression de code:

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, 
    IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
    if (comparer == null)
    {
        comparer = EqualityComparer<TSource>.Default;
    }
    if (first == null)
    {
        throw Error.ArgumentNull("first");
    }
    if (second == null)
    {
        throw Error.ArgumentNull("second");
    }
    using (IEnumerator<TSource> enumerator = first.GetEnumerator())     
    using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            if (!enumerator2.MoveNext() || !comparer.Equals(enumerator.Current, enumerator2.Current))
            {
                return false;
            }
        }
        if (enumerator2.MoveNext())
        {
            return false;
        }
    }
    return true;
}

Comme vous pouvez le voir, il utilise 2 agents recenseurs et les incendies de nombreux appels de méthode qui a sérieusement ralentir. Aussi il ne vérifie pas la longueur, donc dans le pire des cas il peut être ridiculement lent.

Comparer le déplacement de deux itérateurs avec de belles

if (a1[i] != a2[i])

et vous savez ce que je veux dire sur la performance.

Il peut être utilisé dans les cas où la performance n'est pas vraiment de la critique, peut-être dans l'unité de test de code, ou dans le cas d'une courte liste rarement appelées méthodes.

3voto

Imi Points 19

SequenceEqual peut être plus rapide. À savoir dans le cas où presque tout le temps, les deux tableaux ont bien la même longueur et ne sont pas le même objet.

Ce n'est toujours pas la même fonctionnalité que la fonction de l'OP, car il ne comparera pas les valeurs NULL de manière silencieuse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X