FxCop is case-sensitive. VB is annoying.

With profound apologies to VB lovers, there are a few features of the VB compiler that occasionally make me want to start drinking at a very early hour of the day. Perhaps the most troublesome of these is its failure to start screaming bloody murder upon detection of namespaces that differ only by case, even while compiling an assembly that is marked as CLS-compliant. VB 2005 is at least kind enough to conserve the casing from the source code. However, VB 2003 seems to more or less randomly pick one case version and apply it throughout an assembly, and that leads to all sorts of fun and games.

If you’ve developed mixed VB and C# solutions, chances are pretty good that this isn’t exactly news to you since C# tends to get mighty unhappy the resulting changes in namespace casing. However, you might be blissfully unaware that FxCop is also case-sensitive, and that has its own special set of consequences…

At FinRad, we’re still supporting applications that run against .NET 1.1 (and will be for at least a couple more years), and a very large part of that code base is written in VB 2003. Given that this is .NET 1.1 code, we’re using the stand-alone version of FxCop for static analysis, and exclusions are stored in the FxCop project file, not as SuppressMessageAttribute annotations in the source code.

Given that this also happens to be the same code base covered by the bulk of our backlog cleanup efforts, the FxCop project files contain an unusually large number of exclusions. (I’ll write about the reasons for this soon. For now, just trust me: lots more violation exclusions than you might normally expect.) Every now and then, we would end up with a situation where a sizeable chunk of our exclusions would suspiciously disappear, and all the violations they covered would auto-magically become active again. Needless to say, this was terribly annoying, but we chalked it up to gremlins, manually re-created the exclusions, and forged bravely ahead.

A few weeks ago, we hit a really weird problem where an automated build running on an integration server was detecting active FxCop rule violations that couldn’t be duplicated on any developer machines. Several of us tried clean check outs, rebuilding, etc., but without any success at reproducing the problems seen in the automated build. In retrospect, it seems painfully obvious, but the namespace casing problem (which also tended to raise its ugly head in a Visual Studio vs. automated build disjunction with respect to C# callers) didn’t occur to me until I was stuck in traffic that evening. It was the first thing I checked the next morning and, sure enough, the exclusions were registered under the “Something” namespace, but the classes compiled in the automated build now fell under the “SomeThing” namespace.

Some lessons learned:

  • FxCop is case-sensitive.

  • The gremlins actually lived in the VB compiler. (Luckily, they’ve been evicted, but the nasty smells are lingering.)

  • Giving an “aha!” smack to one’s forehead while stuck in traffic will earn some very concerned looks from drivers of neighbouring vehicles.

2 thoughts on “FxCop is case-sensitive. VB is annoying.

  1. We were hit by this “pick-a-random-namespace-casing” behavior of the VB compiler a while ago. Note that it is not truly random but picks one of the casings it found in the source (most likely the first occurrence).

    I turned to LibCheck to detect these kinds of changes. CC.NET runs LibCheck and if it suddenly reports a few hundred classes deleted, we know something’s wrong.


  2. We’ve actually got a custom FxCop rule planned that will be able to detect the case switch. It’s basically a new namespace detector that’s meant to be used for other purposes, but it will flag the case switching too. The new rule didn’t have a very high priority compared to other stuff on my to-do list, but that’s changing pretty quickly, particularly given that someone encountered another problem with dropped exclusions today.

Leave a Reply

Your email address will not be published. Required fields are marked *