Должен ли я вернуть 'NULL' или пустой массив?
Предположим, у вас есть метод, который должен создавать и возвращать какой-то массив. Что делать, если массив не заполняется. Вы возвращаете пустой массив или ноль / ничего?
12 ответов
В.NET лучше возвращать пустой массив, чем ноль, потому что это избавляет вызывающую программу от необходимости писать нулевую проверку и / или рисковать NullReferenceException
; вы увидите, что это общий шаблон в библиотеках базовых классов. Единственный случай, когда вы этого не сделаете, - это маловероятный сценарий, когда пустой массив и ноль имеют разные смысловые значения.
Официальные рекомендации по использованию массива гласят:
Общее правило состоит в том, что нулевые, пустые строковые ("") и пустые (0 элемент) массивы должны обрабатываться одинаково. Вернуть пустой массив вместо пустой ссылки.
Тем не менее, если вы используете.NET 2.0 или более позднюю версию, гораздо лучше вернуть IEnumerable<T>
или одно из его расширяемых производных, такое как Collection<T>
, ReadOnlyCollection<T>
, ICollection<T>
или же IList<T>
(в этом случае я бы по-прежнему имел тенденцию возвращать пустой, а не ноль). Более подробную информацию о том, почему они должны быть предпочтительными, можно найти в блоге Эрика Липперта.
Если вы внимательно прочитаете свой вопрос, вы поймете, что на самом деле вы уже ответили на него сами: вы написали "метод, который должен создавать и возвращать какой-то массив", а не "метод, который должен создавать и, возможно, возвращать массив некоторых". сортировать или нет".
Действительно, это зависит от спецификации. Но так, как вы это сформулировали, метод не может вернуть значение null. Какой стиль я бы предпочел, так или иначе, он просто облегчает работу с краями.
Ваш ответ на этот вопрос, вероятно, в значительной степени зависит от того, на каком языке вы работаете. В таких языках, как C, невозможно вернуть пустой массив, поскольку массив - это просто указатель на некоторый адрес памяти, с которого начинается массив. В этом случае единственный вариант - вернуть нулевой указатель.
Если это действительно не зависит от языка, я бы возвратил пустой объект массива, у большинства контейнеров должна быть функция, такая как IsEmpty(), чтобы вызывающая функция проверяла, есть ли Array IsEmpty, прежде чем что-либо делать с ним.
Если это в C++, я вижу, что оно либо обнуляется, либо если вы передаете ссылку на массив, вы возвращаете размер массива...
Это действительно зависит от того, что звонящий хочет сделать с результатом.
Обычно я возвращаю пустой массив (или Collection, на Java). Это потому, что я обычно прохожу цикл и по желанию добавляю их в коллекцию, а затем возвращаю. Проверка в конце, если Collection.size() == 0
это дополнительный шаг. И затем вызывающая сторона должна добавить дополнительную проверку, чтобы увидеть, равен ли результат 0, и если это так, избегайте итерации коллекции.
Я ценю, что может быть чище возвращать ноль, но это проще сделать, если у меня нет причин для этого
Я возвращаю все, что ожидает звонящий. Если функция должна возвращать "все объекты, для которых X истинно", а X не истинно ни для каких объектов, я возвращаю пустой массив.
если функция даже не смогла выполнить этот поиск "объектов, для которых X истинно", то это не удалось, и она должна как-то сообщить об этом вызывающей стороне. Это можно сделать, вернув null.
Ответ зависит от договора между вызывающим абонентом и функцией. Если вы намереваетесь пометить массив как недействительный, тогда нулевой способ сделать это лучше, чем возвращать массив нулевого размера, поскольку массив нулевого размера может быть допустимым результатом в некоторых ситуациях.
Ну, это действительно зависит от семантики, которую вы хотите дать своему возвращению.
Обычно я использую предварительные и последующие условия для почти всех своих функций / методов. Это означает, что если мой метод должен возвращать массив с данными из определенной обработки, если эта обработка завершается ошибкой, объект должен быть нулевым, а условие post завершится неудачей.
Но в вашем случае я предполагаю, что вы не используете DbC, поэтому, если я ссылаюсь только на ваш вопрос:
Что делать, если массив не заполняется.
Тогда я бы вернул null, так как предполагал, что что-то пошло не так в вашей фразе.
Я предполагаю, что это зависит от того, как язык обрабатывает это.
В C я передаю указатели и всегда включаю указатель, равный размеру массива. Затем вызывающая функция должна предоставить две вещи: массив и размер массива. если функция не заполняет массив, она просто возвращает тот же указатель назад и ничего не делает с размером массива. Обычно я просто реализую структуру векторного типа и работаю с этим.
В perl размер массива обрабатывается неявно, поэтому я просто возвращаю пустой массив, или, если ошибка, я изменяю переменную кода ошибки и возвращаю undef.
В Ja va я использую ArrayLists и использую свойство размера.
Если по какой-то причине в вашем коде нет различий в значении, для результата, являющегося нулевым массивом, вместо простого старого пустого, я бы возвратил пустой. Это также может быть связано с конкретным языком. На некоторых языках у вас может быть только один вариант.
Если вам повезло использовать C#, объявите статическое свойство только для чтения, например:
public static class ArrayUtil<TElement>
{
public static readonly Empty = new TElement[0];
}
(Это в BCL? Почему нет?)
Теперь вы можете вернуться ArrayUtil<int>.Empty
или что угодно. Это в значительной степени устраняет затраты времени выполнения использования пустого массива вместо нуля и дает вызывающей стороне более простое время, чем необходимость иметь дело с нулями.