(This post was imported from an earlier blog. It was first published in 2008.)
Recently, I upgraded to Visual Studio Team System 2008 on my work PC. The main project I work on still targets the .NET Framework 2.0, so I’ve been having a look at other features in VS2008, either new or neglected, until I get the chance to move the project to .NET Framework 3.5.
Under the “somewhat neglected” category of features is Code Analysis. Code Analysis in Visual Studio is essentially an integration of the functionality provided by the free FxCop tool. I’ve used code analysis before, both FxCop and Visual Studio 2005 with respect to .NET projects, as well as Gimpel’s PC-lint on older C and C++ projects. But, I would typically use code analysis only occasionally, to go after egregious guideline violations. I wouldn’t keep it enabled on all builds since it took a while to run, and the remaining long list of mostly-harmless violations made it difficult to see the more important compiler warnings and errors that I immediately cared about.
However, since moving to VS2008 and also getting a much faster workstation, I want to try using code analysis all of the time, on every build, and getting our projects to build with no reported guideline violations. Having code analysis enabled in each build significantly reduces the likelihood of unwanted guideline violations being introduced, since they would be flagged immediately as new code is first compiled.
If you’ve read the Framework Design Guidelines (an excellent book), then you’ll understand many of the guidelines that the code analysis engine implements. More important, the book provides insightful justification for many of the guidelines.
So, both FxCop and Visual Studio’s code analysis (i.e. FxCop-integrated) provide in-your-face warnings of some guidelines that your code may be violating. I say “may be violating” as opposed to “is violating” since guidelines aren’t meant to be hard-and-fast rules, but things that apply most of the time, except when they don’t! Consequently, you may encounter context-based false-positives: a guideline that may be appropriate in most cases, except cases like this one.
For instance, one of the guidelines implemented in VS2008 is a spelling-check on the component words of your public class names, method names, etc. It is a good thing for your identifiers to be spelled correctly. But, if you are using an obscure-but-legitimate term from your application’s business domain that isn’t included in the built-in dictionary, then code analysis will generate a warning.
Thankfully, VS2008 has the ability to use a custom code analysis dictionary. Simply add a CodeAnalysisDictionary.xml file to a project (or to the solution, and add a link to the file from the project), and then set the file’s Build Action to CodeAnalysisDictionary. Your dictionary is then passed to the code analysis engine to prevent false-positives for the words that you know are correct but that aren’t in the basic dictionary. You can find out more about this feature at the Code Analysis Team Blog.
Like the spelling-check, there are other useful but not-always-100%-applicable guidelines which generate false-positives. Fortunately, I found just what I needed to get to my “no reported guideline violations” goal: A way to suppress the false-positives and guideline violation instances that I happen to disagree with.
Essentially, there’s a SuppressMessage attribute in the System.Diagnostics.CodeAnalysis namespace. You can mark up the warning-generating method, class, etc. with SuppressMessage to tell the code analysis engine: “Acknowledged, and please stop reporting it.” You can find out more about SuppressMessage at MSDN - SuppressMessageAttribute Class.
SuppressMessage is great for the obvious false-positive cases. But it can also be applied to the cases I’ve alluded to already where you’ve reviewed the code and simply disagree with the guideline recommendation.
For instance, one guideline CA1021:AvoidOutParameters suggests to not use “out” parameters. The reasoning is that some developers might find out parameters unintuitive to work with. While I agree with that guideline in general, there are specific cases that call for “out” parameters or that have no more desirable alternatives. Once I contemplate and reject the suggestion, I can suppress the message and provide my justification in the optional “Justification” parameter, for the benefit of other human beings who may come across the code. The “Justification” parameter is optional and ignored by the code analysis engine, but best to consider it almost required.
One more useful thing to consider about code analysis: While it helps satisfy the pedantic and perfectionist tendencies of type-A developers, there’s also a pragmatic reason you should want to use code analysis more often: Code analysis helps catch bugs!
For instance, I came across a warning that flagged an unreferenced local variable. It turns out that there was some recently-changed code for a method call, copied from above, that should have differed by one parameter, passing the unreferenced local variable, but the method had instead been passed the same variable from the first call. Code analysis caught that, even though the compiler didn’t warn about the unreferenced local variable. (I’ve seen the compiler optimizer warn about unreferenced class-level fields, but not unreferenced local variables.)
That’s just one instance, but there were others too where code analysis helped locate bugs. Code analysis won’t come right out and say “Hey! There’s certainly a bug here!”, but it can act as a flashlight in the hands of an experienced developer. If other good examples come up again, I’ll post them.
—
Note: I believe Visual Studio’s Code Analysis feature is available only in Team editions, since the integrated FxCop.exe appears to be launched from a “Team Tools” folder. If you have an edition of Visual Studio that doesn’t have code analysis integrated, don’t let that stop you from using FxCop, which you can download separately. I came across this post which explores ways to get FxCop running from Visual Studio 2005, and I imagine similar options are available for Visual Studio 2008.