Правило анализа кода Visual Studio - "Не выставлять общие списки"

Не выставляйте общие списки

ЕСЛИ все мои методы, нужно выставить коллекцию, тогда мне нужно, чтобы пользователь Linq Extension.ToList(), почти везде мне нужно использовать списки или пользовательские коллекции во всем моем коде.

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

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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