Должен ли объект возвращать нуль, а коллекция объектов - пустую коллекцию? - PullRequest
0 голосов
/ 06 октября 2010

Тема возврата нулей, пустых объектов и пустых коллекций возникла сегодня, и мы хотели бы узнать мнение других. Мы прочитали обсуждение , возвращающего нуль для объекта и отдельно обсуждение , возвращающего пустые коллекции , и согласны с отмеченными ответами для обеих тем. Однако в нашем случае у нас есть класс, который содержит класс Foo.Item и класс Foo.Items, который является коллекцией объектов Foo.Item. Если Foo.Item возвращает значение null, возвращает ли коллекция Foo.Items также значение null или пустая коллекция?

Ответы [ 4 ]

1 голос
/ 06 октября 2010

Коллекция - это объект. Есть моменты, когда пустой объект лучше, чем ноль, и это особенно часто встречается с коллекциями, поэтому люди склонны спорить в пользу пустых коллекций. Существуют проблемы, которые могут вызывать пустые объекты, и они чаще встречаются с другими типами (в частности, с семантическими типами значений), поэтому люди склонны спорить с пустыми объектами, если вы не особо упоминаете пустые коллекции.

Однако, в конце дня, и пустая коллекция - это еще и пустой объект.

Стоит учесть, что основной причиной использования пустых коллекций также является та же самая причина, по которой иногда не следует использовать пустые коллекции, а именно то, что нам не нужно проверять на нулевое значение перед выполнением for-each.

Хорошо, пока все хорошо, мы все время возвращаем пустые коллекции, и каждый код, вызывающий их, становится легче писать.

Но подождите минуту, здесь есть недостаток. Это может быть полезно для правительств; ознакомьтесь с новыми заявлениями о пособии по безработице, сделанными в ноябре, и суммируйте, сколько это будет стоить казначейству в этом месяце. Ответ: ноль! Причина в том, что, поскольку сейчас октябрь, у нас нет никаких новых претензий с ноября. Правильный ответ здесь - не пустая коллекция, это ноль.

И, конечно, это тот же самый пример, который люди будут использовать с пустыми объектами, не являющимися коллекциями.

Итак, у каждого из них есть свое место. Так же как и середина; вернуть нулевой объект, но в некоторых случаях объединить его с пустым объектом при получении.

1 голос
/ 06 октября 2010

Вашего абстрактного описания недостаточно. Это (в основном) не техническая проблема с единственным ответом, а вопрос дизайна.

Если в вашем классе также есть Foo.Widget и Foo.Widgets, ответы на Item и Widget не обязательно будут одинаковыми.

Но в общем случае свойства коллекции должны возвращать пустые коллекции, если только для этого нет веской причины. И любой код, потребляющий эту коллекцию, все равно должен проверять наличие нуля. Официальная (библиотечная) рекомендация - двойная безопасность.

0 голосов
/ 06 октября 2010

Вы можете начать с очень простого руководства:

Никогда не возвращайте нулевую ссылку, если можете разумно ее избежать.

По сути, каждая нулевая ссылка является потенциальным приглашением для программной ошибки.Все, что нужно, это не проверять на ноль.Не возвращая значение null, вы почти наверняка упростите жизнь вызывающей стороне.

Последствия этого простого правила:

  • Если тип возвращаемого значения некоторый collectionвведите , а затем верните пустую коллекцию.

  • Если тип возвращаемого значения скалярный тип , возможно, вам придется вернуть нулевые ссылки.Вот некоторые возможные альтернативы:

    1. Возвращение «нулевого», «пустого» или «стандартного» объекта определенного возвращаемого типа.(Подумайте, например, EventArgs.Empty.)

    2. Вы можете определить что-то вроде универсального типа Nullable<T>, который работает как для типов значений, так и для ссылочных типов.(Обоснование: наличие доступа к фактическому возвращаемому значению через явное свойство .Value может сделать для вызывающего абонента более очевидным, что, возможно, ему следует сначала проверить .HasValue. С обычными, неупакованными скалярными типами, это не особенно поощряется илинапомнили проверять нулевые ссылки перед использованием значения.) - (Подумайте по типам Maybe<'a> или Option<'a> и соответствуйте шаблонам в функциональных языках.)

    3. Бросокисключение, если в противном случае нулевая ссылка указывала бы на ошибку.

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

Итак, я не говорю, что избегание нулевых ссылок не будет всегда автоматически облегчать вашу жизнь, само по себе - но я считаю, что руководство все еще очень полезно, потому что оно будетзаставить вас думать о нулевых рефенсиях, об альтернативах и о том, будут ли они более подходящими.

0 голосов
/ 06 октября 2010

В случае объекта вы должны вернуть его как ноль, потому что это позволит быстро проверить обнуляемость. В случае сбора вы должны вернуть пустой список. Пустой список очень важен, потому что потребителю вашего кода не нужно проверять обнуляемость. Учитывая, что они будут использовать foreach, любая обработка, которую они могут выполнять, будет пропущена. Если в пользовательском интерфейсе они пытаются составить таблицу, они покажут пустую таблицу. Пустые коллекции - это путь из-за всех этих преимуществ.

...