I am having trouble with FxCop warning CA1006, Microsoft.Design "DoNotNestGenericTypesInMemberSignatures". Specifically, I am designing a ReportCollection<T>
class that inherits from ReadOnlyCollection<Report<T>>
, and its public
constructor takes an IList<Report<T>>
as a parameter.
The suggestion for fixing this warning is not very useful:
"To fix a violation of this rule, change the design to remove the nested type argument." There are two ways I can see so far to change the design as suggested:
internal
. This doesn't work in my case. The constructor must be public
because this collection class needs to be instantiable by code outside the assembly.Report<T>[]
instead of an IList<Report<T>>
. This is sub-optimal because external code should have the flexibility of using dynamically-sized data structures like List<T>
instead of fixed-size arrays.At this point, I have given up and suppressed this warning. Is there a better solution?
I would take FxCop's warnings as if they were suggestions from an extremely anal-retentive coworker. It's perfectly ok to ignore (suppress) some of the things it suggests.
I agree, another good time to ignore this rule is when you need to say:
Func<IEnumerable<T>>
of course you could use the non-generic IEnumerable, but then any type can be used as long as it implements IEnumerable (non-generic). The purpose of generics (in part) is to restrict the types that are permisable to a given set of types.
I think this rule is very stupid. only need it if you have multiple generic types nested. one layer of nesting is more than safe.
BTW, I think a lot of the LINQ Functions nest generic types as well, so if MS does it, we can too :)
I agree that you can ignore the CA1006 warning in the case of
Func<IEnumerable<T>>
Also you can simplify your code by using delegates and avoid the 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 );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With