Question

It seems strange that the flagship language of .NET would include programming constructs that are not CLS-compliant. Why is that?

Example (from here): Two or more public / protected / protected internal members defined with only case difference

public int intA = 0;
public int INTA = 2; 

or

public int x = 0;

public void X()
{
} 
Was it helpful?

Solution

Even unsigned integers aren't compliant (at least, on the public API), yet they are very important to people who do bit-shifting, in particular when right-shifting (signed and unsigned have different right-shift behaviours).

They are ultimately there to give you the freedom to use them when appropriate. The case-sensitivity one I could get less religious about - despite the convenience of having a field and property differ only by case, I think I could live happily with being forced to use a different name! Especially now we have automatically implemented properties...

This is similar to how it lets you use unsafe - the difference here being that a few unsigned integers aren't going to destabilise the entire runtime, so they don't need quite as strong molly-guards.

You can add:

[assembly: CLSCompliant(true)]

if you like, and the compiler will tell you when you get it wrong.

And finally: most code (by volume) is not consumed as a component. It is written to do a job, and maybe consumed by other code in-house. It is mainly library writers / vendors that need to worry about things like CLS compliance. That is (by the numbers) the minority.

OTHER TIPS

That's not how CLS compliance works. It is something that's your burden. C# doesn't restrain itself to strict compliancy itself, that would make it a language with poor expressivity. Dragging all .NET languages down to the lowest common denominator would have quickly killed the platform as a viable programming environment.

It is up to you to ensure that the publicly visible types in your assembly meet CLS compliancy. Making sure that class members don't differ only by case is very simple to do. Let the compiler help you out by using the [assembly:CLSCompliant(true)] attribute and the compiler will warn you when you slipped.

See http://msdn.microsoft.com/en-us/library/bhc3fa7f.aspx.

CLS is a specification that one opts-in to. Quote from above:

When you design your own CLS-compliant components, it is helpful to use a CLS-compliant tool. Writing CLS-compliant components without this support is more difficult because otherwise you might not have access to all the CLS features you want to use.

Some CLS-compliant language compilers, such as the C# or Visual Basic compilers, enable you to specify that you intend your code to be CLS-compliant. These compilers can check for CLS compliance and let you know when your code uses functionality that is not supported by the CLS. The C# and Visual Basic compilers allow you to mark a program element as CLS-compliant, which will cause the compiler to generate a compile-time error if the code is not CLS-compliant. For example, the following code generates a compiler warning.


Example code from above link:

using System;

// Assembly marked as compliant.
[assembly: CLSCompliant(true)]

// Class marked as compliant.
[CLSCompliant(true)]
public class MyCompliantClass {
   // ChangeValue exposes UInt32, which is not in CLS.
   // A compile-time warning results.
   public void ChangeValue(UInt32 value){ }

   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

This code generates the following C# warning:

Copy warning CS3001: Argument type 'uint' is not CLS-compliant

My two cents about CLS Compliance

The .net languages are all evolutions of languages that were in existence at the time it was created. The languages were crafted so that you could easily convert the base projects into .Net projects without too much development effort. Due to the vast differences between the languages there needed to be some sort of convention for the languages to talk with each other. Take the language examples below:

VB.Net is a language that is derived from the earlier language VB6. It's suppose to be very similar in style to VB6 and as such takes alot of the conventions VB6 used. Since VB6 was suppose to be easy to learn/use by non developers it has certain characteristics that make it more idiot proof. Dynamic typing, case insensitivity being two of these things.

C#.Net/C++.Net are derivatives of the more programmer friendly C++. Since they're an evolution of this language it has things in it that C++ would let you do. Case sensitivity, static typing etc.

Now when faced with two dissimilar languages that they wanted to make interoperable Microsoft did the only reasonable thing. They made restrictions on how the two languages can interact with each other through the use of the basically a software contract. This code can be used in only this way because of the differences in the languages.

For example take VB.Net code calling C# code If the C# code had two functions that differed only in case, X() vs x(), VB.net would never be able to call this code correctly since it is case insensitive. The CLS compliance has to make this illegal. If you look at the other rules they're basically doing the same thing for other language features between the different languages.

I would guess the case insensitivity was only included in CLS compliance so that VB.NET could be CLS compliant. From what I understand, there is no issue if a particular language construct is not CLS compliant unless you are using it in such a way that the incompliant peices are available in the public API of your code.

The hint from Microsoft would seem to be that CLS compliance is only important in code that you are accessing from different languages (such as referencing a C# assembly from a VB.NET project).

I think Microsoft wanted to give developers freedom. No constraints if not necessary. C# is not restricted by CLS because not everyone needs interoperability with VB.

If there was universal agreement about what features should be included in a programming language, the world would only need one programming language (which would include precisely those features everyone agreed should be there). Of course, in reality some people will regard as important features which others don't care about (or even find distasteful). The CLS standard essentially does three things:

  1. It says that certain features are so important that any language which does not include them should be considered inadequate for general-purpose .net programming.
  2. It says that programmers whose libraries don't require any features other than those listed should expect that their libraries will be usable by programmers using any language that is suitable for general-purpose .net programming.
  3. It informs programmers that if parts of their libraries would require the use of features which languages are not required to support, those parts might not be usable in languages which are suitable for .net programming, but don't include the required features.

When languages like vb.net or C# allow the creation of non-CLS compliant programming, what that means is that Microsoft decided that certain features were useful enough to justify inclusion in those languages, but not so wonderful or noncontroversial as to justify mandating all languages include them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top