CLS is a set of specification for programming languages. the. NET environment has no specific limits on the language. As long as it complies with the CLS specification, we can say that it is a language compatible with. net. In the actual project development process, we can use different languages. For example, when we need to introduce some third-party products, we cannot ensure that the language used in the assembly is the same as the programming language we use. Therefore, ensure that the Assembly must be CLS compatible.
CLS compatibility actually uses a "maximum public Denominator" method to achieve interoperability. To create CLS compatible Assembly, we need to follow two principles: 1) the types of parameters and return values used by all public and protected members in the Assembly must be CLS compatible; 2) public and protected members that are not CLS compatible, there must be a CLS-compatible alternative.
We can add the clscompliant feature in the Assembly to ensure that the compiled assembly is CLS compatible.
[ assembly: CLSCompliant( true ) ]
After this feature is used, the compiler ensures that the Assembly is compatible with CLS during compilation. If it is not compatible, the compiler reports an error.
The second principle above, we need to ensure that a language-independent access method is provided for the Assembly users, at the same time, make sure that the objects incompatible with Cls are not hidden in the Assembly interface through the polymorphism mechanism.
Not all. NET languages Support Operator overloading. Therefore, it is best to implement Operator Overloading in the form of helper methods.
For the parameters in the interface, we should also pay attention to the following code.
Code
1 // Hiding the non-compliant event argument:
2 public delegate void MyEventHandler(
3 object sender, EventArgs args );
4
5 public event MyEventHandler OnStuffHappens;
6
7
8 internal class BadEventArgs : EventArgs
9 {
10 internal UInt32 ErrorCode;
11 }
12
13
14 // Code to raise Event:
15 BadEventArgs arg = new BadEventArgs( );
16 arg.ErrorCode = 24;
17
18 // Interface is legal, runtime type is not:
19 OnStuffHappens( this, arg );
20
The above Code makes CLS incompatible with parameters in the interface in a multi-state manner.
Let's look at the following code.
Code
[ assembly:CLSCompliant( true ) ]
public interface IFoo
{
void DoStuff( Int32 arg1, string arg2 );
}
public interface IFoo2
{
// Non-CLS compliant, Unsigned int
void DoStuff( UInt32 arg1, string arg2 );
}
For the foo interface in the above Code, we use the clscompliant feature for decoration, indicating that this interface is CLS compatible. Note that this interface may be CLS compatible only when the interface is defined in a CLS-compatible assembly. It is not enough to define the interface only according to the CLS specification, that is, if the foo interface is not in a CLS-compatible Assembly, although the parameters used in its declaration and the type of returned values are CLS-compatible, the interface itself is not CLS-compatible, we should not call the dostuff () method by referencing the foo interface.
For the foo2 interface in the above Code, it is a CLS incompatible interface. Therefore, if a class shows that this interface is implemented, the class becomes CLS incompatible.
If you want the assembly to be CLS compatible, you must ensure that the following content is CLS compatible:
- Base Class
- Return values of public or protected methods/attributes
- Public alive protected method/indexer Parameter
- Parameters of running current events
- Public APIs declared or implemented
CLS compatibility requires us to spend some time thinking about the public excuses of programs from the perspective of other languages. We do not need to limit all code to the CLS compatibility scope, you only need to avoid CLS incompatible structures in the public interface.