IComparable поведение для нулевых аргументов - PullRequest
9 голосов
/ 27 декабря 2011

Я реализую IComparable и IComprable<T> в одном из моих классов.Есть ли рекомендации о том, как метод CompareTo в каждом случае должен вести себя, когда ему дан нулевой аргумент?Должен ли он вернуть положительное число или выбросить ArgumentNullException?Или это поведение может отличаться в зависимости от класса реализации?

Я видел документацию MSDN ( здесь и здесь ), но по этому вопросу ничего не сказано.Любая помощь будет оценена.

Ответы [ 3 ]

12 голосов
/ 27 декабря 2011

Я видел документацию MSDN, но по этому вопросу ничего не сказано

Да, но не очень ясно. В документации говорится:

По определению, любой объект сравнивает больше (или следует) Ничто, а две нулевые ссылки сравниваются равными друг другу.

Документация сбивает с толку, потому что она смешивает идиомы из C # (ноль) и VB (ничего) в одном предложении Я упомяну об этом менеджеру документации.

Обратите внимание, что то же правило применяется к типам значений, допускающих значение NULL. Например, если вы сортируете список целых чисел, допускающих значение NULL, то для целей сортировки 1 считается больше нуля. Быть осторожен; это не то, как по умолчанию в C # сравниваются обнуляемые целые числа.

10 голосов
/ 27 декабря 2011

Обе ссылки MSDN для IComparable.CompareTo() и IComparable<T>.CompareTo() указывают следующее:

По определению, любой объект сравнивается больше (или следует) Nothing, а две нулевые ссылки сравниваются равными друг другу.

Nothing в VB соответствует null в C #.

Обратите внимание, что в предыдущем абзаце указано:

Значение сравнений «меньше чем», «равно» и «больше чем» зависит от конкретной реализации.

Но ссылки на экземпляры, которые не равны NULL, всегда больше, чем ссылки на NULL, независимо от того, как вы сравниваете экземпляры вашего класса.

7 голосов
/ 13 мая 2013

Убедитесь, что вы используете Object.ReferenceEquals, чтобы проверить, является ли аргумент, переданный CompareTo, нулевым.Избегайте использования операторов == и! = В методах CompareTo, потому что кто-то может фактически следовать предложению MSDN о делегировании этих операторов обратно в метод CompareTo, который, в свою очередь, создал бы бесконечный цикл и переполнение стека (!) В мгновение ока.

Вот модель, как вы можете попытаться реализовать метод CompareTo:

public class Piano : IComparable<Piano>
{

    public float Mark { get; set; }

    public int CompareTo(Piano other)
    {
        // The very basic implementation of CompareTo

        if (object.ReferenceEquals(other, null))
            return 1;   // All instances are greater than null

        return Mark.CompareTo(other.Mark);

    }

}

Весь исходный код с пояснениями по этому адресу.

...