Why does C# include programming constructs that are not CLS-compliant?
Asked Answered
P

7

9

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()
{
} 
Propane answered 16/2, 2011 at 21:24 Comment(6)
From the article, "it supports many non-CLS-compliant codes mainly to support and maintain the legacy language nativity"?Menashem
I did see that . . . but I'm hoping to either have that elaborated on or get some more definitive answer. Thanks though. :-)Propane
I believe unsigned ints are not CLS compliant either. Good question.Colorist
I'm having difficulty answering the question because it seems strange to me that you would find it strange. Can you explain what you find so strange about this?Ustulation
It's strange because MS created a Common Language Specification, and then their two flagship languages, VB.NET and C#.NET, don't even comply! LOL But, I got my answer. Thank you though.Propane
I don't know how you elaborate on "the legacy language nativity". Does sanjeevi mean the birth of C# or the birth of Christ? Either way that sentence doesn't make sense. There are examples here of how you can use VB or C# in non-compliant fashion, but where does the .NET Framework not comply?Zealand
F
17

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.

Feasible answered 16/2, 2011 at 21:38 Comment(0)
A
14

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.

Alveolate answered 16/2, 2011 at 21:41 Comment(0)
M
5

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

Mascon answered 16/2, 2011 at 21:42 Comment(0)
P
3

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.

Pallet answered 16/2, 2011 at 22:8 Comment(0)
W
2

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).

Weakminded answered 16/2, 2011 at 21:29 Comment(5)
That's the thing that puzzles me though. In a world of .NET, here you have two flagship languages (VB.NET and C#.NET) that would have issues interoperating unless you are very careful!Propane
Just to enforce wllmsaccnt... CLS is there to allow interop between .NET languages. If you know that your assembly is only going to be used on it's own or with other C# assemblies then non-CLS constructs will work. If you will ever need to reference your assembly from another .NET language then you will need to comply with the CLS. I'll come back in a minute with a definitive as to whether VS will even let you try...Interrelation
VS2010 will let you reference a non cls assembly and even create an instance of a non-CLS class but any non-cls items will not be available - in the example public int intA = 0; public int INTA = 2; neither of these will be available but you could access public int intB = 1;Interrelation
@Kim: Are you sure? I would imagine if you were using C# that it would allow you to see the non-CLS members which were conformant to C#'s language. I think you would be able to see any of the common type members, which are a superset of the common language specification members.Weakminded
Sorry - I wasn't clear - I referenced a non CLS C# assembly from a VB.NET assembly and the non-conformant items were not available. I've not tried the other way round but I'm sure you're right.Interrelation
P
1

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.

Paulo answered 16/2, 2011 at 21:39 Comment(0)
M
0

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.

Mayemayeda answered 14/11, 2012 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.