2008-12-21 6 views
2

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

3

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.

+0

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? –

+0

Bon - avec ça je peux voir où ça peut poser problème. Merci! –

+0

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. –

2

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

+0

Excellent point Eric, je pense que c'est exactement le problème auquel je suis impliqué. Merci beaucoup pour votre aide! – salocinx