Правило анализа кода Visual Studio - «Не открывать общие списки» - PullRequest
10 голосов
/ 15 июня 2010

Не открывать общие списки

Если все мои методы нужны для раскрытия коллекции, тогда мне нужно использовать расширение Linq .ToList (), почти везде, где мне нужно использоватьсписки или пользовательские коллекции во всем моем коде.

В этом случае .ToList () игнорирует правило, верно?Или есть метод, такой как копирование списка или что-то, чтобы исправить нарушение и все же вернуть список?

Ответы [ 3 ]

8 голосов
/ 13 июля 2010

Это правило действительно может быть шумным, но есть несколько очень веских причин избегать List<T> в коде библиотеки. Все зависит от контекста. Вот несколько вещей, которые следует учитывать перед отключением правила или подавлением данного вхождения:

  • List<T> часто является плохим выбором для входных параметров, поскольку вынуждает вызывающих абонентов копировать данные без необходимости. Я видел много кода, который объявляет параметры как List<T> или T[], когда достаточно IEnumerable<T>.

  • List<T> может быть плохим выбором и для недвижимости. Рассмотрим следующие альтернативы:

    public class Course {
        public List<Course> Prerequisites { get; }
    }
    public class Course {
        public Collection<Course> Prerequisites { get; }
    }
    

    Предполагается, что вызывающая сторона может изменить предварительные условия курса, изменив коллекцию. В этом случае, если мы используем List<Course>, класс Course не сможет уведомляться об изменении предварительных условий, поскольку List<T> не предоставляет никаких обратных вызовов модификации. Таким образом, использование List<T> в этом контексте похоже на использование произвольного числа открытых полей. С другой стороны, мы можем создать подкласс Collection<T> и переопределить его виртуальные объекты, чтобы получать уведомления об изменениях.

List<T> лучше всего работает как возвращаемое значение, когда полное право собственности на коллекцию передается вызывающей стороне. Вот почему Enumerable.ToList() на самом деле совершенно разумно и не нарушает дух правила.

Теперь, когда я думаю об этом, допустим List<T> в качестве возвращаемого значения из методов, но продолжая отмечать List<T> свойства и параметры, вероятно, значительно улучшит отношение сигнал / шум правила ...

8 голосов
/ 15 июня 2010

Я отключаю это правило, потому что не считаю его действительным.Если вы хотите вернуть коллекцию, которая содержит число O(1) и не является прямой ссылкой на внутреннее поле, List<T> - лучший выбор.

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

3 голосов
/ 15 июня 2010

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

Вам нужно будет принять решение по каждому правилу, чтобы проверить, действительно ли оно для ваших обстоятельств. Мне нравится использовать анализ, так как иногда он обнаруживает некоторые ошибки, но я всегда заканчиваю тем, что отключаю определенные правила (например, у меня часто есть catch Exception в качестве окончательного универсального элемента только потому, что мне нужно регистрировать все виды ошибок даже если они не могут быть обработаны).

...