Quando sarà un operatore di confronto rendere Ordina lanciare un ArgumentException?

StackOverflow https://stackoverflow.com/questions/384632

  •  23-08-2019
  •  | 
  •  

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?

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top