Есть ли хорошие обходные пути для предупреждения FxCop CA1006?
У меня возникают проблемы с Предупреждение FxCop CA1006, Microsoft.Design "DoNotNestGenericTypesInMemberSignatures". В частности, я разрабатываю класс ReportCollection<T>
, который наследует от ReadOnlyCollection<Report<T>>
, а его конструктор public
принимает IList<Report<T>>
в качестве параметра.
Предложение по исправлению этого предупреждения не очень полезно:
"Чтобы устранить нарушение этого правила, измените дизайн, чтобы удалить аргумент вложенного типа." До сих пор я вижу два способа изменить дизайн, как это было предложено:
- Сделайте конструктор
internal
. Это не работает в моем случае. Конструктор должен быть public
, потому что этот класс коллекции должен быть экземпляром кода вне сборки.
- Сделайте конструктор вместо
IList<Report<T>>
вместо Report<T>[]
. Это неоптимально, поскольку внешний код должен обладать гибкостью использования структур данных с динамическим размером, таких как List<T>
вместо массивов фиксированного размера.
В этот момент я отказался и подавил это предупреждение. Есть ли лучшее решение?
Ответы
Ответ 1
Я согласен, еще раз хорошее время игнорировать это правило, когда вам нужно сказать:
Func<IEnumerable<T>>
конечно, вы могли бы использовать не-общий IEnumerable, но тогда можно использовать любой тип, если он реализует IEnumerable (non-generic). Целью дженериков (частично) является ограничение типов, допустимых для заданного набора типов.
Я думаю, что это правило очень глупо. это нужно только в том случае, если у вас есть несколько типичных типов. один слой вложенности более безопасен.
Кстати, я думаю, что многие функции LINQ также содержат общие типы, поэтому, если MS это делает, мы можем также:)
Ответ 2
Я бы принял предупреждения FxCop, как если бы они были предложениями крайне анально-ретентивного коллеги. Совершенно нормально игнорировать (подавлять) некоторые вещи, которые он предлагает.
Ответ 3
Я согласен с тем, что вы можете игнорировать предупреждение 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 );
}