Introduction
If you are writing .Net classes, which will be used by other .Net classes irrespective of the language they are implemented, then your code should conform to the CLS [Common Language Specification]. This means that your class should only expose features that are common across all .Net languages. The following are the basic rules that should be followed when writing a CLS-compliant C# code.
- Unsigned types should not be part of the public interface of the class. What this means is public fields should not have unsigned types like uint or ulong, public methods should not return unsigned types, and parameters passed to public functions should not have unsigned types. However, unsigned types can be part of private members.
- Unsafe types like pointers should not be used with public members. However, they can be used with private members.
- Class names and member names should not differ only based on their case.
Example. we cannot have two methods named MyMethod and MYMETHOD.
- Only properties and methods may be overloaded; Operators should not be overloaded.
The above-mentioned rules should be followed only for the types and members that are publicly exposed to your program. Private classes, private methods, and local variables need to follow the rules.
By default, the C# complier does not check for CLS compliance with the code. We should explicitly make the C# compiler check for CLS compliance by using the CLSCompliantAttribute class. By specifying the value of true to this attribute, we specify that the C# compiler should check for the CLS compliance of the code. The CLSCompliantAttribute can be applied to assemblies, modules, types, and members.
For marking an entire assembly as CLS-compliant, the following syntax is used.
using System;
[assembly: CLSCompliant(true)]
For marking a particular method as CLS compliant, the following syntax is used.
[CLSCompliant(true)]
public void MyMethod()
If you mark an assembly as CLSCompliant and if any of the publicly exposed types of members are not CLS compliant, then the compiler would raise an error, as shown in the following example.
Example
using System;
// Setting CLSCompliant attribute to true
[assembly: CLSCompliant(true)]
[CLSCompliant(true)]
public class Test
{
public void MyMethod()
{
}
// Error because methods differ only in their case
public void MYMETHOD()
{
}
static void Main()
{
}
}
Compiling the above code will result in the following error.
error CS3005: Identifier 'Test.MYMETHOD()' differing only in case is not CLS-compliant.
A program section cannot be marked as CLScompliant if the section, that encloses it, is not marked as CLScompliant.
Example. A class cannot be marked as CLS-compliant if the assembly is not marked as CLS-compliant.
using System;
// Setting CLSCompliant attribute to true
[CLSCompliant(true)]
public class Test
{
public void MyMethod()
{
}
// Error because methods differ only in their case
public void MYMETHOD()
{
}
static void Main()
{
}
}
Compiling the above code will result in the following error.
'Test' cannot be marked as CLS compliant because the assembly is not marked as compliant.
You can also mark a particular section of a CLS-compliant class as non-CLS-compliant by setting the CLS-compliant attribute to false for the particular section. The compiler will not enforce CLS compliance for sections that are marked as non-CLS compliant.
Example
using System;
// Setting CLSCompliant attribute to true
[assembly: CLSCompliant(true)]
[CLSCompliant(true)]
public class Test
{
public void MyMethod()
{
}
// Not an error because the method is not CLS compliant
[CLSCompliant(false)]
public void MYMETHOD()
{
}
static void Main()
{
}
}
Compiling the above code will not result in an error, as the method is marked as non-CLS compliant.
Following are some situations that may cause the C# compiler to raise an error.
- If your class methods are identical but differ only by 'out' or 'ref,'.
- If a publicly exposed member starts with an underscore (_).
- If an abstract member is marked for non-CLS compliance within a CLS-compliant class.
Conclusion
If you develop applications that conform to the CLS, your program will be interoperable with a wide range of. Net-supported programming languages. Therefore, your application is likely to have a wider customer base than a non-CLS-compliant version of your application. You can make sure that the C# programs you develop are CLS compliant by using the CLSCompliantAttribute, which will cause the compiler to raise errors if the program is not CLS compliant.