FxCop and CLS Compliance

After finding out that VB.NET does not enforce CLS compliance (even with the CLSCompliant attribute set to True), I thought I could use FxCop to check this. Although ServerGeek said that FxCop complains about non-CLS compliance, I did not see such behavior. I created a simple, non-CLS compliant VB.NET assembly:

Namespace TestCls
    Public Class BadStuff
        Public Function CheckThis() As UInt32
            Return UInt32.Parse("5")
        End Function
    End Class
End Namespace

And got no complaints from FxCop (1.21) about it not being CLS compliant -- which it isn't since it exposes a non-CLS datatype (UInt32). Further research showed Peter Drayton mentioning FxCop as a possible use for this. Sam Gentile also commented that a tool to verify CLS compliance would be nice. I'm surprised there is no standalone tool for checking CLS compliance. Anyone working on a custom rules engine for FxCop for this purpose?

And please don't send me emails saying "csc.exe" is the tool you use to enforce CLS compliance! :)

10 Comments

  • Of course this is CLS compliant code. The UInt32 type is System.UInt32, which is a normal type to expose, since it's in the System namespace.





    After all, if exposing a type that is in the System namespace makes the code NOT CLS compliant, I think the definition of CLS compliant is not usable :)

  • Unsigned ints are supported by the framework, but they are *not* CLS compliant. Just try this with that "other" cls checking tool:





    using System;





    [assembly: CLSCompliant(true)]





    namespace TestCls


    {


    public class BadStuff


    {


    public UInt32 CheckThis()


    {


    return UInt32.Parse("5");


    }


    }


    }





    You'll get:





    Class1.cs(9): Return type of 'TestCls.BadStuff.CheckThis()' is not CLS-compliant.

  • How is it that when I use valuetype XYZ defined in the System namespace it is NOT CLS compliant (UInt32) but if I use my struct, it IS CLS compliant.





    It's indeed true (tested it after reading your response) that UInt32 will fail CLS compliance testing in C#. Absurd. It's a System type, a native type of the .NET library, the same as all the other types in the .NET library.





    After reading this, I'll remove every CLSCompliance test from my code, until MS fixes this OR comes with a good explanation.

  • LOL. Yet another reason to use the C# compiler. Morts aren't supposed to care about this type of thing. ;-). Seriously though, if you are creating CLS compliant code, why are you using VB? If you ask me, that is pretty lame in the first place, since using VB adds the extra VisualBasic assembly dependancy, which isn't part of the framework specs. So, IMO, by using VB you have already taken a big step in the wrong direction for platform compatibility (I guess you could argue that you are only worried about those running the MS CLR, but I wouldn't expect someone worried about CLS compliance to ignore such things).

  • Giving warnings on CLSCompliance violations was an unfortunate cut from the existing VB product, and is definitely something we're looking at doing in a future release. (As for Microsoft.VisualBasic, it's part of the platform. If the complaint is that it's not part of the ECMA specs, well, there's a lot of .NET that isn't in those...)

  • What's also crap about CLS compliance is: VB.NET doesn't support unsigned ints, therefore every unsigned int value type exposing type is not CLS compliant. What if my language doesn't support 64bit ints? Or 32bit ints and 64bit ints? Is the language then forcing that CLS compliance is changed with the rule that Int64's are not compliant either? After all, they expose a 64bit long member which is not supported by my imaginary language (example), as UInt32 is exposing an uint member which is not supported by VB.NET.

  • Yes, but if I am using C# and I am worried about compatibility, I can eliminate calls to those portions of the framework which are not in the spec :-).





    Just out of curiosity, can Microsoft.VisualBasic be redistributed with your progs and run on any CLR implementation (ie. is there anything that ties it to MS version of the .NET framework, or does it run fine on any implementation that meets the CLR spec)?

  • Jesse,





    The inclusion of the VisualBasic assembly can be overridden using the command-line compiler switch "/novbruntimeref". However, your code will fail if you have any VB-specific stuff (which is quite common in VB code!). I've tried a couple of small projects with that switch and didn't have to make too many changes to get the code to compile.

  • Cool deal. Though if you can't use any VB specific stuff, it kind of takes the fun out of using VB in the first place ;-).

  • Jesse,





    Agreed. I'm sure on a larger project I'd hit a road block that could only be solved by including the runtime.





    I'm also curious as to the redistribution rights of the VB runtime assembly.

Comments have been disabled for this content.