Quando sarà un operatore di confronto rendere Ordina lanciare un ArgumentException?
Domanda
La documentazione per Ordina dice che Ordina getterà un ArgumentException se "l'implementazione di operatore di confronto ha causato un errore durante l'ordinamento. Per esempio, di confronto potrebbe non restituire 0 quando si confrontano un elemento con se stesso".
A parte l'esempio dato, qualcuno mi può dire quando questo sarebbe altrimenti accaduto?
Soluzione
L'algoritmo di ordinamento (QuickSort) si basa su un'implementazione IComparer prevedibile. Dopo poche decine di strati di indirezione nel BCL si finisce in questo modo:
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));
}
}
Andando un po 'più nella realizzazione QuickSort, si vede il codice come questo:
while (comparer.Compare(keys[a], y) < 0)
{
a++;
}
while (comparer.Compare(y, keys[b]) < 0)
{
b--;
}
In pratica se l'IComparer misbehaves chiamata Quicksort con gettare un IndexOutOfRangeException, che è avvolto n ArgumentException.
Ecco un altro esempio di cattiva IComparer di
class Comparer: IComparer<int>
{
public int Compare(int x, int y)
{
return -1;
}
}
Quindi credo che, la risposta breve è, in qualsiasi momento l'implementazione IComparer non confrontare costantemente i valori come definito nella documentazione:
Confronta due oggetti e restituisce una valore che indica se è meno , uguale o superiore alla altro.
Altri suggerimenti
Mi sono imbattuto in questo oggi, e dopo avere indagato, ho scoperto che a volte il mio operatore di confronto era stato chiamato con x e y benessere riferimenti a lo stesso oggetto , e il mio operatore di confronto non stava tornando a 0. Una volta che ho fissa che, ho smesso di ottenere l'eccezione.
HTH,
Eric