Tuesday, August 20, 2013

FxCop Rule CA1724:TypeNames​ShouldNot​Match​Namespaces — Not just for Morts

This is another one of those rules that seems like a needless bit of pedantry, but there is a scenario where violating it can lead to unexpected behaviour, depending on your coding style. The documentation for the rule itself says about violations that

For new development, there are no known scenarios where you must exclude a warning from this rule. For shipping libraries, you might have to exclude a warning from this rule.

and most of the time it is harmless, but there is one wrinkle involving code sharing the namespace -- in the case I hit it, with some extension methods -- where it's not so obvious what you have to do to make your code compile.

I hit this when refactoring an old library to take one base class that managed a whole bunch of concerns into a more fine-grained set of classes (since most uses didn't need the full set of overheads, and some wanted to select a different set).

where the subclass has to be disambiguated from the namespace -- but that's mostly harmless as the shared systematic prefix means we don't need a using now. And this is where we set the little trap for ourselves when we add code to the namespace.

After refactoring the equivalent library code now looks like this

and in most cases we'd just change the namespace reference in the consuming code, and indicate the subject of the extension methods (the magic this.), like

and it would "just work". Instead, because of the way we've worked around the namespace clash above, it reports "The name 'AsString' does not exist in the current context"; because normally you'd already have an explicit using Systematic.Prefix.Library.Classic;, and the class declared just with its unqualified name,

And you still have to have that full using directive, to bring the extension methods into scope, even while the class itself still needs to be explicitly qualified.

Fortunately, R# will, as soon as you put the this. into place, prompt you to put the using directive in place.

No comments :