I like to keep my .net code FxCop clean -- and especially when writing an FxCop rule set, it's pretty much part of the ground rules -- even though some of the rules tend at times towards coding for Mort to use your library (rather than educating him). However, FxCop does tend to assume you're coding in any .net language you like, so long as it's C#.
Take this example:
which emulates the C#
as keyword (or C++
dynamic_cast<C *>() ) by contrast to the F# :?> which is more akin to
dynamic_cast<C &>(). I don't mind the
CA1004:GenericMethodsShouldProvideTypeParameter warning this gives -- but taking the F# idiomatic
'a and generating
warning : CA1709 : Microsoft.Naming : On method 'Patterns.As<a>(object)', correct the casing of 'a' in generic type parameter name 'a' by changing it to 'A'. warning : CA1704 : Microsoft.Naming : On method 'Patterns.As<a>(object)', consider providing a more meaningful name than generic type parameter name 'a'. warning : CA1715 : Microsoft.Naming : On method 'Patterns.As<a>(object)', prefix generic type parameter name 'a' with 'T'.
seems a bit excessive, even though replacing it with
'Target, like you might if you actually had to write it in C# as well, will suppress all three.
And that's just in code I write.
When the code subject to warnings is itself generated, that tends to add a degree of insult to injury. As in
which conjures up
CA1707:IdentifiersShouldNotContainUnderscores from variables
state_1 in generated code that looks like
CA1804:RemoveUnusedLocals for name
x in the guard pattern
which maps to
x has to be scoped that way, as well as
CA1804:RemoveUnusedLocals for entities only present in generated code.
That's debug build. In release build (not normally subject to FxCop, since you don't want to have
SuppressMessage attributes floating around in what you ship) we get a different set of messages from differently shaped IL -- for
we at last get the entirely plausible
CA1801:ReviewUnusedParameters (by contrast debug build's function body that assigns the argument to a write-only local causes no warnings!), and for the obvious combinator for chaining state with the
"'arg_1', a parameter, is cast to type 'Either<x, a>._Right' multiple times in method 'Local.op_GreaterMultiplyGreater... -- but, surprisingly, no warning about underscores in names this time!
This certainly makes it harder to do the right thing, when none of the warnings, apart from the underscores one, actually seem like things that could really be called bugs as such. And it's also harder to frame alternative FxCop rules to use instead of the standard ones, rules that work with F# idiom, beyond possibly the generic type parameter naming cluster.
The debug build for the Feb 2010 CTP is unchanged from this; the release build produces more warnings for both the above cases, mainly about naming -- but also including
"In member 'Module1.op_GreaterMultiplyGreater<q, x, a, b>(q, Either<x, a>, FSharpFunc<q, FSharpFunc<a, Either<x, b>>>)', remove the underscores from parameter name 'arg_0'."