Есть ли хорошие обходные пути для предупреждения FxCop CA1006? - PullRequest
24 голосов
/ 06 января 2009

У меня проблемы с предупреждением FxCop CA1006 , Microsoft.Design "DoNotNestGenericTypesInMemberSignatures". В частности, я проектирую класс ReportCollection<T>, который наследуется от ReadOnlyCollection<Report<T>>, а его конструктор public принимает в качестве параметра IList<Report<T>>.

Предложение по исправлению этого предупреждения не очень полезно:

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

  1. Сделать конструктор internal. Это не работает в моем случае. Конструктор должен быть public, потому что этот класс коллекции должен быть инстанцируемым кодом вне сборки.
  2. Заставьте конструктора взять Report<T>[] вместо IList<Report<T>>. Это неоптимально, поскольку внешний код должен иметь гибкость использования структур данных динамического размера, таких как List<T>, вместо массивов фиксированного размера.

В этот момент я сдался и подавил это предупреждение. Есть ли лучшее решение?

Ответы [ 3 ]

31 голосов
/ 06 января 2009

Я бы воспринял предупреждения FxCop, как если бы они были советами от чрезвычайно анально-сдержанного сотрудника. Совершенно нормально игнорировать (подавлять) некоторые вещи, которые он предлагает.

22 голосов
/ 23 ноября 2010

Согласен, еще одно хорошее время игнорировать это правило, когда вам нужно сказать:

Func<IEnumerable<T>>

Конечно, вы можете использовать неуниверсальный IEnumerable, но тогда можно использовать любой тип, если он реализует IEnumerable (неуниверсальный). Цель обобщений (частично) состоит в том, чтобы ограничить типы, допустимые для данного набора типов.

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

Кстати, я думаю, что многие из функций LINQ также содержат общие типы, поэтому, если MS это сделает, мы тоже сможем:)

4 голосов
/ 14 октября 2015

Я согласен, что вы можете игнорировать предупреждение CA1006 в случае

Func<IEnumerable<T>>

Также вы можете упростить свой код с помощью делегатов и избежать CA1006:

public delegate IEnumerable<T> ChildrenDel<T>( T parent);

// was: GetDescendants<T>( this T item, Func< T, IEnumerable< T > > children )

public static IEnumerable< T > GetDescendants<T>( this T item, ChildrenDel<T> children )
{
    var stack = new Stack< T >();
    do {
        children( item ).ForEach( stack.Push );

        if( stack.Count == 0 )
            break;

        item = stack.Pop();

        yield return item;
    } while( true );
}
...