Лучшая практика при возврате массива значений (.NET) - PullRequest
3 голосов
/ 20 февраля 2009

Обычно мои методы следующие:

public List<int> Method1(int input)
{
    var output = new List<int>();
    //add some items to output
    return output;
}

Но FxCop рекомендует другую реализацию IList вместо List, но я не могу вспомнить, какая именно. Альтернативы включают возвращение его в виде IList, ICollection или IEnumerable для большей гибкости или совсем другим способом, как показано в коде ниже

public int[] Method2(int input)
{
    var output = new List<int>();
    //add some items to output
    return output.ToArray();
}

Из всех альтернатив, всех предусмотренных и всех возможностей, что считается наилучшей практикой?

Ответы [ 8 ]

6 голосов
/ 20 февраля 2009

IEnumerable / IEnumerable , если вам не нужен список, тогда вы должны вернуть IList

5 голосов
/ 20 февраля 2009

У Эрика Липперта есть хороший пост о том, почему возвращать массив обычно плохая идея .

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

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

IEnumerable<T> - лучшее место для начала. С появлением LINQ очень мало вещей, которые вызывающий абонент не может сделать легко, просто учитывая перечисление. Если вызывающему абоненту иногда требуется список, достаточно просто позвонить .ToList().

Если вызывающим, вероятно, будет определенная потребность индексировать возвращаемую коллекцию, или если они, вероятно, захотят сами изменить коллекцию (вставка / удаление / переупорядочение элементов), рассмотрите возможность использования IList<T>.

5 голосов
/ 20 февраля 2009

В «Руководстве по проектированию структуры» (2-е изд) в §8.3.1 есть достаточно много, чтобы сказать о коллекциях как возвращаемых значениях, резюме:

  • НЕ предоставляют настраиваемые свойства коллекции.
  • DO использовать Collection<T> или подкласс Collection<T> для свойств или возвращаемых значений, представляющих коллекции чтения / записи.
  • DO использовать ReadOnlyCollection<T>, подкласс ReadOnlyCollection<T> или в редких случаях IEnumerable<T> для свойств или возвращаемых значений, представляющих коллекции только для чтения.

(и более, но эти три захватывают ядро).

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

Я бы вернул IList<T> и гарантировал, что я не определяю фактический тип, который я возвращаю, если только я не возвращал итератор (когда я использовал бы IEnumerable<T>).

3 голосов
/ 20 февраля 2009

ReadOnlyCollection<T> - это еще один вариант.

2 голосов
/ 20 февраля 2009

Возвращает интерфейс, который вам нужен в коде, вызывающем этот метод.

Если вам нужно выполнить список действий с результатом, верните IList<T>. Если вам просто нужно перечислить результаты, верните IEnumerable<T>.

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

1 голос
/ 20 февраля 2009

Я почти всегда использую List, потому что он дает мне методы, которые я часто нахожу наиболее полезными.

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

1 голос
/ 20 февраля 2009

Это зависит от ваших требований. Все сказано и сделано, итерация по строго типизированным массивам является самой быстрой среди всех типов коллекций. Если вам не нужно изменять их размер / добавлять / искать, массивы вполне подойдут.

1 голос
/ 20 февраля 2009

Это зависит.

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

Можете ли вы уточнить предупреждение FxCop?

Kent

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