La documentation pour Sort dit que Sort lancera une exception ArgumentException si "l'implémentation du comparateur a provoqué une erreur pendant le tri." Par exemple, le comparateur ne peut pas renvoyer 0 lors de la comparaison d'un élément avec lui-même. " En dehors de l'exemple donné, quelqu'un peut-il me dire quand cela se produirait autrement?Quand un Comparaison fera-t-il trier une ArgumentException?
Répondre
L'algorithme de tri (QuickSort) repose sur une implémentation IComparer prévisible. Après quelques dizaines de couches de indirection dans la BCL vous vous retrouvez à cette méthode:
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
try
{
...
ArraySortHelper<T>.QuickSort(keys, index, index + (length - 1), comparer);
}
catch (IndexOutOfRangeException)
{
...
throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", values));
}
}
Pour aller un peu plus loin dans la mise en œuvre QuickSort, vous voyez le code comme ceci:
while (comparer.Compare(keys[a], y) < 0)
{
a++;
}
while (comparer.Compare(y, keys[b]) < 0)
{
b--;
}
En gros, si le IComparer se comporte mal l'appel Quicksort avec lancer une exception IndexOutOfRangeException, qui est enveloppée dans n ArgumentException.
Voici un autre exemple de mauvaise donc je suppose que ce IComparer
class Comparer: IComparer<int>
{
public int Compare(int x, int y)
{
return -1;
}
}
, la réponse est, à tout moment votre implémentation IComparer ne pas comparer systématiquement les valeurs telles que définies dans la documentation:
Compares deux objets et renvoie une valeur indiquant si l'un est supérieur, égal ou supérieur à l' autre.
je suis tombé aujourd'hui, et après enquête, je trouve que, parfois, mon comparateur était appelé avec x et y des références étant de le même objet, et mon comparateur ne retournerait pas 0. Une fois que je fixe , J'ai arrêté d'avoir l'exception.
HTH,
Eric
Excellent point Eric, je pense que c'est exactement le problème auquel je suis impliqué. Merci beaucoup pour votre aide! – salocinx
Merci - c'est à peu près à quel point je l'ai fait avant de se tourner vers SO. L'erreur d'origine semble être une exception IndexOutOfRangeException. Comment cela est-il lié à la prédicabilité du comparateur? –
Bon - avec ça je peux voir où ça peut poser problème. Merci! –
J'ai examiné cela un peu plus. Si je ne me trompe pas, le coup de pied peut être assez floconneux la plupart du temps. Ce n'est que lorsque l'index ci-dessus dépasse les limites du tableau que le problème se produit. Évidemment, ce n'est guère utile que le comparateur devrait juste faire la bonne chose. –