Когда Comparer заставит Sort выдать ArgumentException? - PullRequest
3 голосов
/ 21 декабря 2008

В документации для Сортировка говорится, что Сортировка вызовет ArgumentException, если "Реализация компаратора вызвала ошибку во время сортировки. Например, компаратор может не вернуть 0 при сравнении элемента с самим собой."

Помимо приведенного примера, кто-нибудь может сказать мне, когда это могло бы произойти?

Ответы [ 2 ]

4 голосов
/ 21 декабря 2008

Алгоритм сортировки (QuickSort) основан на предсказуемой реализации IComparer. После нескольких десятков слоев косвенного обращения в BCL вы в конечном итоге выберете следующий метод:

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));
    }
}

Пройдя немного дальше в реализации QuickSort, вы увидите код, подобный следующему:

    while (comparer.Compare(keys[a], y) < 0)
    {
        a++;
    }
    while (comparer.Compare(y, keys[b]) < 0)
    {
        b--;
    }

В основном, если IComparer неправильно ведет себя вызов Quicksort с броском IndexOutOfRangeException, который обернут в n ArgumentException.

Вот еще один пример плохого IComparer

class Comparer: IComparer<int>
{
    public int Compare(int x, int y)
    {
        return -1;
    }
}

Так что, я думаю, краткий ответ таков, что каждый раз, когда ваша реализация IComparer последовательно не сравнивает значения, определенные в документации:

Сравнивает два объекта и возвращает значение, указывающее, меньше ли чем, равно или больше, чем другой.

3 голосов
/ 11 октября 2011

Я столкнулся с этим сегодня, и после исследования я обнаружил, что иногда мой компаратор вызывался с x и y, ссылающимися на тот же объект , и мой компаратор не возвращал 0. Как только я исправил что я перестал получать исключение.

НТН,

Эрик

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...