.NET Framework 4 Common Language Specification To fully interact with other objects regardless of the language they were implemented in, objects must expose to callers only those features that are common to all the languages they must interoperate with. For this reason, the Common Language Specification (CLS), which is a set of basic language features needed by many applications, has been defined. The CLS rules define a subset of the Common Type System; that is, all the rules that apply to the common type system apply to the CLS, except where stricter rules are defined in the CLS. The CLS helps enhance and ensure language interoperability by defining a set of features that developers can rely on to be available in a wide variety of languages. The CLS also establishes requirements for CLS compliance; these help you determine whether your managed code conforms to the CLS and to what extent a given tool supports the development of managed code that uses CLS features. If your component uses only CLS features in the API that it exposes to other code (including derived classes), the component is guaranteed to be accessible from any programming language that supports the CLS. Components that adhere to the CLS rules and use only the features included in the CLS are said to be CLS-compliant components. Most of the members defined by types in the .NET Framework Class Library are CLS-compliant. However, some types in the class library have one or more members that are not CLS-compliant. These members enable support for language features that are not in the CLS. The types and members that are not CLS-compliant are identified as such in the reference documentation, and in all cases a CLS-compliant alternative is available. For more information about the types in the .NET Framework class library, see the .NET Framework Class Library. The CLS was designed to be large enough to include the language constructs that are commonly needed by developers, yet small enough that most languages are able to support it. In addition, any language construct that makes it impossible to rapidly verify the type safety of code was excluded from the CLS so that all CLS-compliant languages can produce verifiable code if they choose to do so. For more information about verification of type safety, see Managed Execution Process. The following table summarizes the features that are in the CLS and indicates whether the feature applies to both developers and compilers (All) or only compilers. It is intended to be informative, but not comprehensive. For details, see the specification for the Common Language Infrastructure, Partition I, which is available on the Microsoft Developer Network (MSDN) Web site. Feature | Applies to | Description |
|---|
General | | | Visibility | All | CLS rules apply only to those parts of a type that are exposed outside the defining assembly. | Global members | All | Global static fields and methods are not CLS-compliant. | Naming | | | Characters and casing | All | CLS-compliant language compilers must follow the rules of Annex 7 of Technical Report 15 of the Unicode Standard 3.0, which governs the set of characters that can start and be included in identifiers. This standard is available from the Web site of the Unicode Consortium. For two identifiers to be considered distinct, they must differ by more than just their case. | Keywords | Compilers | CLS-compliant language compilers supply a mechanism for referencing identifiers that coincide with keywords. CLS-compliant language compilers provide a mechanism for defining and overriding virtual methods with names that are keywords in the language. | Uniqueness | All | All names within a CLS-compliant scope must be distinct, even if the names are for two different kinds of members, except where the names are identical and resolved through overloading. For example, the CLS does not allow a single type to use the same name for a method and a field. | Signatures | All | All return and parameter types appearing in a type or member signature must be CLS-compliant. | Types | | | Primitive types | All | The .NET Framework class library includes types that correspond to the primitive data types that compilers use. Of these types, the following are CLS-compliant: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr, and String. For more information about these types, see the table of types in the .NET Framework Class Library. | Boxed types | All | Boxed value types (value types that have been converted to objects) are not part of the CLS. Instead, use System..::.Object, System..::.ValueType, or System..::.Enum, as appropriate. | Visibility | All | Type and member declarations must not contain types that are less visible or accessible than the type or member being declared. | Interface methods | Compilers | CLS-compliant language compilers must have syntax for the situation where a single type implements two interfaces and each of those interfaces requires the definition of a method with the same name and signature. Such methods must be considered distinct and need not have the same implementation. | Closure | All | The individual members of CLS-compliant interfaces and abstract classes must be defined to be CLS-compliant. | Constructor invocation | All | Before it accesses any inherited instance data, a constructor must call the base class's constructor. | Typed references | All | Typed references are not CLS-compliant. (A typed reference is a special construct that contains a reference to an object and a reference to a type. Typed references enable the common language runtime to provide C++-style support for methods that have a variable number of arguments.) | Type Members | | | Overloading | All | Indexed properties, methods, and constructors are allowed to be overloaded; fields and events must not be overloaded. Properties must not be overloaded by type (that is, by the return type of their getter method), but they are allowed to be overloaded with different numbers or types of indexes. Methods are allowed to be overloaded only based on the number and types of their parameters, and in the case of generic methods, the number of their generic parameters. Operator overloading is not in the CLS. However, the CLS provides guidelines about providing useful names (such as Add()) and setting a bit in metadata. Compilers that choose to support operator overloading should follow these guidelines but are not required to do so. | Uniqueness of overloaded members | All | Fields and nested types must be distinct by identifier comparison alone. Methods, properties, and events that have the same name (by identifier comparison) must differ by more than just the return type. | Conversion operators | All | If either op_Implicit or op_Explicit is overloaded on its return type, an alternate means of providing the conversion must be provided. | Methods | | | Accessibility of overridden methods | All | Accessibility must not be changed when overriding inherited methods, except when overriding a method inherited from a different assembly with FamilyOrAssembly accessibility. In this case, the override must have Family accessibility. | Argument lists | All | The only calling convention supported by the CLS is the standard managed calling convention; variable length argument lists are not allowed. (Use the ParamArray keyword in Microsoft Visual Basic and the params keyword in C# for variable number of arguments support.) | Properties | | | Accessor metadata | Compilers | The getter and setter methods that implement the methods of a property are marked with the mdSpecialName identifier in the metadata. | Modifiers | All | The property and its accessors must all be static, all be virtual, or all be instance. | Accessor names | All | Properties must follow specific naming patterns. For a property called Name, the getter method, if defined, will be called get_Name and the setter method, if defined, will be called set_Name. | Return type and arguments | All | The type of the property is the return type of the getter and the type of the last argument of the setter. The types of the parameters of the property are the types of the parameters to the getter and the types of all but the final parameter of the setter. All these types must be CLS-compliant and cannot be managed pointers; they must not be passed by reference. | Events | | | Event methods | All | The methods for adding and removing an event must both be present or absent. | Event method metadata | Compilers | The methods that implement an event must be marked with the mdSpecialName identifier in the metadata. | Accessor accessibility | All | The accessibility of the methods for adding, removing, and raising an event must be identical. | Modifiers | All | The methods for adding, removing, and raising an event must all be static, all be virtual, or all be instance. | Event method names | All | Events must follow specific naming patterns. For an event named MyEvent, the add method, if defined, will be named add_MyEvent, the remove method, if defined, will be named remove_MyEvent, and the raise method will be named raise_MyEvent. | Arguments | All | The methods for adding and removing an event must each take one parameter whose type defines the type of the event, and that type must be derived from System..::.Delegate. | Pointer Types | | | Pointers | All | Pointer types and function pointer types are not CLS-compliant. | Interfaces | | | Member signatures | All | CLS-compliant interfaces must not require the definition of non-CLS-compliant methods in order to implement them. | Member modifiers | All | CLS-compliant interfaces cannot define static methods, nor can they define fields. They are allowed to define properties, events, and virtual methods. | Reference Types | | | Constructor invocation | All | For reference types, object constructors are only called as part of the creation of an object, and objects are only initialized once. | Class Types | | | Inheritance | All | A CLS-compliant class must inherit from a CLS-compliant class (System..::.Object is CLS-compliant). | Arrays1 | | | Element types | All | Array elements must be CLS-compliant types. | Dimensions | All | Arrays must have a fixed number of dimensions that is greater than zero. | Bounds | All | All dimensions of an array must have a zero lower bound. | Enumerations | | | Underlying type | All | The underlying type of an enumeration must be a built-in CLS integer type (Byte, Int16, Int32, or Int64). | FlagsAttribute | Compilers | The presence of the System..::.FlagsAttribute custom attribute on the definition of an enumeration indicates that the enumeration should be treated as a set of bit fields (flags), and the absence of this attribute indicates the type should be viewed as a group of enumerated constants. It is recommended that languages use either the FlagsAttribute or language-specific syntax for distinguishing between these two types of enumerations. | Field members | All | Literal static fields of an enumeration must be the same type as the type of the enumeration itself. | Exceptions | | | Inheritance | All | Objects that are thrown must be of type System..::.Exception or inherit from System.Exception. | Custom Attributes | | | Value encodings | Compilers | CLS-compliant compilers are required to deal with only a subset of the encodings of custom attributes (the representation of custom attributes in metadata). The only types that are permitted to appear in these encodings are: System..::.Type, System..::.String, System..::.Char, System..::.Boolean, System..::.Byte, System..::.Int16, System..::.Int32, System..::.Int64, System..::.Single, System..::.Double, and any enumeration type based on a CLS-compliant base integer type. | Metadata | | | CLS compliance | All | Types whose CLS compliance differs from that of the assembly in which they are defined must be so marked with the System..::.CLSCompliantAttribute. Similarly, members whose CLS compliance differs from that of their type must also be marked. If a member or type is marked as not CLS-compliant, a CLS-compliant alternative must be provided. | Generics | | | Type names | Compilers | The name of a generic type must encode the number of type parameters declared on the type. The name of a nested generic type must encode the number of type parameters newly introduced to the type. | Nested types | Compilers | Nested types must have at least as many generic parameters as the enclosing type. Generic parameters in a nested type correspond by position to the generic parameters in its enclosing type. | Constraints | All | A generic type must declare sufficient constraints to guarantee that any constraints on the base type or interfaces are satisfied by the generic type constraints. | Constraint types | All | Types used as constraints on generic parameters must themselves be CLS-compliant. | Member signatures | All | The visibility and accessibility of members (including nested types) in an instantiated generic type is considered to be scoped to the specific instantiation rather than the generic type declaration as a whole. | Generic methods | All | For each abstract or virtual generic method, there must be a default concrete (non-abstract) implementation |
1. Jagged arrays — that is, arrays of arrays — are CLS-compliant. In the .NET Framework version 1.0, the C# compiler mistakenly reports that they are not.

See Also
|
.NET Framework 4 Common Language Specification Para poder interactuar completamente con otros objetos, sea cual sea el lenguaje en que se hayan implementado, los objetos deben exponer a los llamadores sólo aquellas características que sean comunes para todos los lenguajes con los que deben interoperar. Por este motivo, se ha definido Common Language Specification (CLS), que es un conjunto de características de lenguaje básicas requeridas por la mayoría de las aplicaciones. Las reglas de CLS definen un subconjunto del Sistema de tipos comunes, es decir, todas las reglas que se aplican al sistema de tipos común se aplican también a CLS, salvo que se definan reglas más estrictas en CLS. CLS ayuda a mejorar y garantizar la interoperabilidad entre lenguajes mediante la definición de un conjunto de características en las que se pueden basar los programadores y que están disponibles en una gran variedad de lenguajes. CLS también establece los requisitos de conformidad con CLS; estos requisitos permiten determinar si el código administrado cumple la especificación CLS y hasta qué punto una herramienta dada admite la programación de código administrado que utilice las características de CLS. Si un componente sólo utiliza las características de CLS en la API que expone a otro código (incluidas las clases derivadas), se garantiza que se puede obtener acceso al componente desde cualquier lenguaje de programación que admita CLS. Los componentes que cumplen las reglas de CLS y usan sólo las características incluidas en CLS se conocen como componentes conformes a CLS. La mayoría de los miembros definidos por tipos en la Biblioteca de clases de .NET Framework son conformes a CLS. Sin embargo, algunos tipos de la biblioteca de clases tienen uno o más miembros que no son conformes a CLS. Estos miembros permiten el uso de características de lenguaje que no se encuentran en CLS. Los tipos y miembros que no son conformes a CLS se identifican como tales en la documentación de referencia y, en todos los casos, existe una alternativa conforme a CLS. Para obtener más información sobre los tipos de la biblioteca de clases de .NET Framework, vea Biblioteca de clases de .NET Framework. CLS se diseñó de manera que fuese lo suficientemente amplio como para incluir las construcciones de lenguaje que normalmente necesitan los programadores y lo suficientemente pequeño como para que todos los lenguajes pudieran admitirlo. Además, se ha excluido de CLS cualquier construcción de lenguaje de la que no se puede verificar rápidamente la seguridad de tipos del código, de manera que todos los lenguajes conformes a CLS pueden generar código que es posible comprobar. Para obtener más información sobre la comprobación de la seguridad de tipos, vea Proceso de ejecución administrada. En la tabla siguiente, se resumen las características que se incluyen en CLS y se indica si cada característica se aplica a programadores y compiladores (Todos) o sólo a compiladores. Se pretende que sea informativa, pero no detallada. Para obtener información detallada, consulte la especificación de Common Language Infrastructure, Partition I, disponible en el sitio web Microsoft Developer Network (MSDN). Característica | Se aplica a | Descripción |
|---|
General | | | Visibilidad | Todos | Las reglas de CLS se aplican sólo a las partes de un tipo que se expongan fuera del ensamblado que realiza la definición. | Miembros globales | Todos | Los campos y métodos static globales no son conformes a CLS. | Nombres | | | Caracteres y mayúsculas | Todos | Los compiladores de lenguaje conformes a CLS deben seguir las reglas del anexo 7 del informe técnico 15 del estándar Unicode 3.0, que controla el conjunto de caracteres que pueden iniciar e incluirse en los identificadores. Este estándar está disponible en el sitio web de Unicode Consortium. Para que dos identificadores se consideren distintos, deben diferenciarse por algo más que el uso de mayúsculas o minúsculas. | Keywords | Compiladores | Los compiladores de lenguajes conformes a CLS proporcionan un mecanismo para hacer referencia a identificadores que coinciden con palabras clave. Los compiladores de lenguajes conformes a CLS proporcionan un mecanismo para definir y reemplazar los métodos virtuales por nombres que son palabras clave en el lenguaje. | Exclusividad | Todos | Todos los nombres de un ámbito conforme a CLS deben ser distintos, incluso cuando los nombres sean para dos clases de miembros diferentes, excepto cuando los nombres son idénticos y se resuelven mediante sobrecarga. Por ejemplo, CLS no permite que un tipo único use el mismo nombre para un método y un campo. | Prototipos | Todos | Todos los tipos devueltos y los tipos de parámetros que aparecen en un prototipo de tipo o miembro deben ser conformes a CLS. | Tipos | | | Tipos primitivos | Todos | La biblioteca de clases de .NET Framework incluye tipos que se corresponden con los tipos de datos primitivos que usan los compiladores. De entre estos tipos, son conformes a CLS los siguientes: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr y String. Para obtener más información sobre estos tipos, vea la tabla de tipos de la Biblioteca de clases de .NET Framework. | Tipos encuadrados | Todos | Los tipos de valor encuadrados (tipos de valor que se han convertido en objetos) no son parte de CLS. Utilice en su lugar System..::.Object, System..::.ValueType o System..::.Enum, según corresponda. | Visibilidad | Todos | Las declaraciones de tipos y miembros no deben contener tipos que sean menos visibles o accesibles que el tipo o miembro que se va a declarar. | Métodos de interfaz | Compiladores | Los compiladores de lenguajes conformes a CLS deben incluir sintaxis para el caso de que un tipo único implemente dos interfaces y cada una de esas interfaces requiera la definición de un método con el mismo nombre y el mismo prototipo. Tales métodos se deben considerar distintos y no necesitan tener la misma implementación. | Cierre | Todos | Los miembros individuales de interfaces y clases abstractas conformes a CLS deben definirse para ser conformes a CLS. | Invocación de constructores | Todos | Para poder tener acceso a datos de instancias heredadas, un constructor debe llamar al constructor de la clase base. | Referencias a tipos | Todos | Las referencias a tipos no son conformes a CLS. Una referencia a un tipo es una construcción especial que contiene una referencia a un objeto y una referencia a un tipo. Las referencias a tipos permiten que Common Language Runtime proporcione compatibilidad con los estilos de C++ a los métodos que tienen un número variable de argumentos. | Miembros de tipos | | | Sobrecarga | Todos | Se permite la sobrecarga de propiedades indizadas, métodos y constructores; no se deben sobrecargar campos y eventos. Las propiedades no se deben sobrecargar por tipo (es decir, por el tipo de valor devuelto de su método Get), pero se pueden sobrecargar con números o tipos de índices diferentes. Sólo se permite la sobrecarga de métodos si se basa en el número y en los tipos de parámetros y, en el caso de los métodos genéricos, si se basa en el número de parámetros genéricos. La sobrecarga de operadores no se incluye en CLS. Sin embargo, CLS proporciona directrices sobre cómo incluir nombres útiles (como Add()) y cómo establecer un bit en los metadatos. Se recomienda que los compiladores que elijan incluir la sobrecarga de operadores sigan estas directrices, aunque no están obligados a ello. | Exclusividad de miembros de sobrecarga | Todos | Los campos y los tipos anidados deben distinguirse únicamente por comparación de identificador. Los métodos, las propiedades y los eventos que tengan el mismo nombre (por comparación de identificador) deben distinguirse por algo más que el tipo de valor devuelto. | Operadores de conversión | Todos | Si op_Implicit u op_Explicit se sobrecarga sobre el tipo de valor devuelto, se debe incluir una forma alternativa para proporcionar la conversión. | Métodos | | | Accesibilidad de los métodos reemplazados | Todos | La accesibilidad no se debe cambiar al reemplazar los métodos heredados, excepto cuando se reemplace un método heredado a partir de un ensamblado diferente con accesibilidad FamilyOrAssembly. En este caso, el reemplazo debe tener accesibilidad Family. | Listas de argumentos | Todos | La única convención de llamada admitida por CLS es la convención de llamada administrada estándar; no se permiten las listas de argumentos de longitud variable. (Utilice la palabra clave ParamArray de Microsoft Visual Basic y la palabra clave params de C# para permitir un número variable de argumentos.) | Propiedades | | | Metadatos de descriptor de acceso | Compiladores | Los métodos Get y Set que implementan los métodos de una propiedad se marcan con el identificador mdSpecialName en los metadatos. | Modificadores | Todos | La propiedad y sus descriptores de acceso deben ser static, virtual o instance. | Nombres de descriptores de acceso | Todos | Las propiedades deben seguir los patrones de nombres específicos. Para una propiedad denominada Name, el método Get, si se define, se denominará get_Name y el método Set, si se define, se denominará set_Name. | Tipo de valor devuelto y argumentos | Todos | El tipo de la propiedad es el tipo de valor devuelto del método Get y el tipo del último argumento del método Set. Los tipos de los parámetros de la propiedad son los tipos de los parámetros del método Get y los tipos de todos los parámetros del método Set, excepto el último. Todos estos tipos deben ser conformes a CLS y no pueden ser punteros administrados; no deben pasarse por referencia. | Eventos | | | Métodos de evento | Todos | Los métodos para agregar y quitar un evento deben estar ambos presentes o ausentes. | Metadatos de los métodos de evento | Compiladores | Los métodos que implementen un evento deben marcarse con el identificador mdSpecialName en los metadatos. | Accesibilidad del descriptor de acceso | Todos | La accesibilidad de los métodos para agregar, quitar y provocar un evento debe ser idéntica. | Modificadores | Todos | Los métodos para agregar, quitar y provocar un evento deben ser static, virtual o instance. | Nombres de los métodos de evento | Todos | Los eventos deben seguir los patrones de nombres específicos. Para un evento denominado MyEvent, el método Add, si se define, se denominará add_MyEvent, el método Remove, si se define, se denominará remove_MyEvent y el método Raise se denominará raise_MyEvent. | Argumentos | Todos | Los métodos que se utilizan para agregar y quitar un evento deben tomar un parámetro cuyo tipo defina el tipo del evento, y ese tipo debe derivarse de System..::.Delegate. | Tipos de puntero | | | Punteros | Todos | Los tipos de puntero y los tipos de puntero a función no son conformes a CLS. | Interfaces | | | Prototipos de miembros | Todos | Las interfaces conformes a CLS no deben requerir la definición de métodos no conformes a CLS para su implementación. | Modificadores de miembros | Todos | Las interfaces conformes a CLS no pueden definir métodos estáticos ni pueden definir campos. Pueden definir propiedades, eventos y métodos virtuales. | Tipos de referencia | | | Invocación de constructores | Todos | Para los tipos de referencia, se llama a los constructores de objetos sólo como parte de la creación de un objeto, y los objetos se inicializan una sola vez. | Tipos de clase | | | Herencia | Todos | Las clases conformes a CLS deben heredarse de clases conformes a CLS (System..::.Object es conforme a CLS). | Matrices1 | | | Tipos de elemento | Todos | Los elementos de matriz deben ser tipos conformes a CLS. | Dimensiones | Todos | Las matrices deben tener un número fijo de dimensiones, es decir, tienen que ser mayores que cero. | Límites | Todos | Todas las dimensiones de una matriz deben tener un límite menor que cero. | Enumeraciones | | | Tipo subyacente | Todos | El tipo subyacente de una enumeración debe ser un tipo entero integrado en CLS (Byte, Int16, Int32 o Int64). | FlagsAttribute | Compiladores | La presencia del atributo personalizado System..::.FlagsAttribute en la definición de una enumeración indica que la enumeración debe tratarse como un conjunto de campos de bits (marcadores), y la ausencia de este atributo indica que el tipo debe verse como un grupo de constantes enumeradas. Se recomienda que en los lenguajes se utilice FlagsAttribute o sintaxis específica del lenguaje para distinguir estos dos tipos de enumeraciones. | Miembros de campo | Todos | Los campos static literales de una enumeración deben ser del mismo tipo que el tipo de la enumeración. | Excepciones | | | Herencia | Todos | Los objetos que se produzcan deberán ser de tipo System..::.Exception o heredarse de System.Exception. | Atributos personalizados | | | Codificaciones de valores | Compiladores | Los compiladores conformes a CLS deben tratar sólo un subconjunto de las codificaciones de los atributos personalizados (la representación de los atributos personalizados en los metadatos). Los únicos tipos que pueden aparecer en estas codificaciones son: System..::.Type, System..::.String, System..::.Char, System..::.Boolean, System..::.Byte, System..::.Int16, System..::.Int32, System..::.Int64, System..::.Single, System..::.Double y cualquier tipo de enumeración basado en un tipo entero base conforme a CLS. | Metadatos | | | Conformidad con CLS | Todos | Los tipos que tienen una conformidad con CLS distinta a la del ensamblado en el que se definen deberán marcarse correspondientemente mediante System..::.CLSCompliantAttribute. De manera similar, los miembros cuya conformidad con CLS sea diferente de la de su tipo también se deben marcar. Si un miembro o tipo está marcado como no conforme a CLS, debe proporcionarse una alternativa conforme a CLS. | Genéricos | | | Nombres de tipo | Compiladores | El nombre de un tipo genérico debe codificar el número de parámetros de tipo declarados en el tipo. El nombre de un tipo genérico anidado debe codificar el número de parámetros de tipo recién introducidos en el tipo. | Tipos anidados | Compiladores | Los tipos anidados deben tener, como mínimo, el mismo número de parámetros genéricos que el tipo contenedor. Los parámetros genéricos de un tipo anidado se corresponden por posición con los parámetros genéricos del tipo contenedor. | Restricciones | Todos | Todo tipo genérico deberá declarar restricciones suficientes como para garantizar que cualquier restricción de las interfaces o del tipo base se vea satisfecha por las restricciones del tipo genérico. | Tipos de restricción | Todos | Los tipos que se utilizan como restricciones en parámetros genéricos deberán ser conformes a CLS. | Prototipos de miembros | Todos | Se entiende que la visibilidad y accesibilidad de los miembros (incluidos los tipos anidados) de un tipo genérico del que se ha creado una instancia quedan restringidas al ámbito específico de creación de instancias, y no a la declaración de tipos genéricos en general. | Métodos genéricos | Todos | Cada método genérico abstracto o virtual deberá tener su propia implementación concreta (no abstracta) predeterminada |
1. La matrices escalonadas, es decir, matrices de matrices son conformes a CLS. En la versión 1.0 de .NET Framework, el compilador de C# informa erróneamente de que no lo son.

Vea también
|