Common Language Specification
The Common Language Specification (CLS) is a part of the standardized specification of the .NET Framework originally defined by Microsoft, and later standardized by the European Computer Manufacturers Association (ECMA). A key feature of .NET Framework is that applications written in different languages can interoperate with one another, taking advantage of inheritance, polymorphism, exceptions and other features. But for this to happen, the interoperable .NET code must adhere to a set of 41 rules known as the Common Language Specification (CLS).
The CLS is defined in the Common Language Infrastructure, Partition I standard, which is a small subset of Common Language Infrastructure (CLI), ECMA Standard 335. The CLS describes what a developer must do to ensure that a component is CLS-compliant. Most (but not all) members of the .NET framework class libraries are CLS-compliant. The ECMA standard is in its fourth edition as of 2006, and the same standard has also been adopted by the International Standards Organization as ISO/IEC 23271:2006.
If you design a CLS-compliant component, your code will be interoperable with a wide range of programming languages; therefore, your library is likely to have a wider customer base than a non-CLS-compliant version would. The 41 CLS rules are summarized below. The clause references refer to sections within the Partition I document. Items within a class may be explicitly marked as CLS-compliant or not using the System.CLSCompliantAttribute. The rules apply only to items that are marked as CLS-compliant.
1. CLS rules apply only to those parts of a type that are accessible or visible outside of the defining assembly (see Section 7.3).
2. Members of non-CLS compliant types shall not be marked CLS-compliant. (see clause 7.3.1).
3. The CLS does not include boxed value types (see clause 8.2.4).
4. Assemblies shall follow Annex 7 of Technical Report 15 of the Unicode Standard 3.0 (ISBN 0-201-61633-5) governing the set of characters permitted to start and be included in identifiers, available on-line at []. For CLS purposes, two identifiers are the same if their lowercase mappings (as specified by the Unicode locale-insensitive, 1-1 lowercase mappings) are the same. That is, for two identifiers to be considered different under the CLS they shall differ in more than simply their case. However, in order to override an inherited definition the CLI requires the precise encoding of the original declaration be used (see clause 8.5.1).
5. All names introduced in a CLS-compliant scope shall be distinct independent of kind, except where the names are identical and resolved via overloading. That is, while the CTS allows a single type to use the same name for a method and a field, the CLS does not (see clause 8.5.2).
6. Fields and nested types shall be distinct by identifier comparison alone, even though the CTS allows distinct signatures to be distinguished. Methods, properties, and events that have the same name (by identifier comparison) shall differ by more than just the return type, except as specified in CLS Rule 39 (see clause 8.5.2).
7. The underlying type of an enum shall be a built-in CLS integer type (see clause 8.5.2).
8. There are two distinct kinds of enums, indicated by the presence or absence of the System.FlagsAttribute custom attribute. One represents named integer values, the other named bit flags that can be combined to generate an unnamed value. The value of an enum is not limited to the specified values (see clause 8.5.2).
9. Literal static fields of an enum shall have the type of the enum itself (see clause 8.5.2).
10. Accessibility shall not be changed when overriding inherited methods, except when overriding a method inherited from a different assembly with accessibility Family-or-Assembly. In this case the override shall have accessibility family (see clause 126.96.36.199).
11. All types appearing in a signature shall be CLS-compliant (see clause 8.6.1).
12. The visibility and accessibility of types and members shall be such that types in the signature of any member shall be visible and accessible whenever the member itself is visible and accessible. For example, a public method that is visible outside its assembly shall not have an argument whose type is visible only within the assembly (see clause 8.6.1).
13. The value of a literal static is specified through the use of field initialization metadata (see Partition II). A CLS compliant literal must have a value specified in field initialization metadata that is of exactly the same type as the literal (or of the underlying type, if that literal is an enum). (see clause 188.8.131.52).
14. Typed references are not CLS-compliant (see clause 184.108.40.206).
15. The varargs constraint is not part of the CLS, and the only calling convention supported by the CLS is the standard managed calling convention (see clause 220.127.116.11).
16. Arrays shall have elements with a CLS-compliant type and all dimensions of the array shall have lower bounds of zero. Only the fact that an item is an array and the element type of the array be required to distinguish between overloads. When overloading is based on two or more array types the element types shall be named types. (see clause 8.9.1).
17. Unmanaged pointer types are not CLS-compliant (see clause 8.9.2).
18. CLS-compliant interfaces shall not require the definition of non-CLS compliant methods in implement them (see clause 8.9.4).
19. CLS-compliant interfaces shall not define static methods, nor shall they define fields (see clause 8.9.4).
20. CLS-compliant classes, value types, and interfaces shall not require the implementation of non- CLS-compliant interfaces (see clause 18.104.22.168).
21. An object constructor shall call some class constructor of its base class before any access occurs inherited instance data. This does not apply to value types, which need not have constructors (see clause 22.214.171.124).
22. An object constructor shall not be called except as part of the creation of an object, and an object shall not be initialized twice (see clause 126.96.36.199).
23. System.Object is CLS-compliant. Any other CLS-compliant class shall inherit from a CLS compliant class (see clause 8.9.9).
24. The methods that implement the getter and setter methods of a property shall be marked SpecialName in the metadata (see Partition II) (see clause 8.11.3).
25. The accessibility of a property and of its accessors shall be identical (see clause 8.11.3).
26. A property and its accessors shall all be static, all be virtual, or all be instance (see clause 8.11.3).
27. The type of a property shall be the return type of the getter and the type of the last argument the setter. The types of the parameters of the property shall be the types of the parameters getter and the types of all but the final parameter of the setter. All of these types shall be compliant, and shall not be managed pointers (i.e. shall not be passed by reference) (see clause 8.11.3).
28. Properties shall adhere to a specific naming pattern. See Section 10.4. The SpecialName attribute referred to in CLS rule 24 shall be ignored in appropriate name comparisons and shall adhere identifier rules (see clause 8.11.3).
29. The methods that implement an event shall be marked SpecialName in the metadata (see Partition II) (see clause 8.11.4).
30. The accessibility of an event and of its accessors shall be identical (see clause 8.11.4).
31. The add and remove methods for an event shall both either be present or absent (see clause 8.11.4).
32. The add and remove methods for an event shall each take one parameter whose type defines type of the event and that shall be derived from System.Delegate (see clause 8.11.4).
33. Events shall adhere to a specific naming pattern. See Section 10.4. The SpecialName attribute referred to in CLS rule 29 shall be ignored in appropriate name comparisons and shall adhere identifier rules (see clause 8.11.4).
34. The CLS only allows a subset of the encodings of custom attributes. The only types that shall appear in these encodings are: System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System. and any enumeration type based on a CLS-compliant base integer type (see Section 9.7).
35. The CLS does not allow publicly visible required modifiers (modreq, see Partition II), but does allow optional modifiers (modopt, see Partition II) they do not understand(see Section 9.7).
36. Global static fields and methods are not CLS-compliant (see Section 9.8).
37. Only properties and methods may be overloaded (see Section 1 on 10.2).
38. Properties, instance methods, and virtual methods may be overloaded based only on the number and types of their parameters, except the conversion operators named op_Implicit and op_Explicit which may also be overloaded based on their return type (see Section 10.2).
39. If either op_Implicit or op_Explicit is overloaded on its return type, an alternate means of providing the coercion shall be provided (see clause 10.3.3).
40. Objects that are thrown shall be of type System.Exception or inherit from it (see Section 10.5). Nonetheless, CLS compliant methods are not required to block the propagation of other types of exceptions.
41. Attributes shall be of type System.Attribute, or inherit from it (see Section 10.6).