Должен ли я вернуть '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 или что угодно. Это в значительной степени устраняет затраты времени выполнения использования пустого массива вместо нуля и дает вызывающей стороне более простое время, чем необходимость иметь дело с нулями.

Другие вопросы по тегам