CLS规范
功能 | 适用于 | 说明 |
---|---|---|
常规 | ||
可见性 |
所有 | CLS 规则仅适用于类型中在定义程序集之外公开的部分。 |
全局成员 |
所有 | 全局静态字段和方法不符合 CLS。 |
命名 | ||
字符和大小写 |
所有 | 符合 CLS 的语言编译器必须遵循 Unicode 标准 3.0 技术报告 15 的附件 7 中的规则,其中规定了可以用在标识符的开头以及包含在标识符中的字符。在 www.unicode.org/unicode/reports/tr15/tr15-18.html 上可以找到此标准。
要让两个标识符被认为是不同的,它们要在除大小写不同之外尚有其他不同之处。 |
关键字 |
Compilers | 符合 CLS 的语言编译器提供用于引用与关键字相符的标识符的机制。符合 CLS 的语言编译器提供定义和用名称(该名称是语言中的关键字)重写虚方法的机制。 |
唯一性 |
所有 | 除了通过重载来解析的名称可以相同之外,符合 CLS 的范围中的所有名称都必须是不同的,即使在这些名称用于两种不同类型的成员时也应如此。例如,CLS 不允许一个类型对方法和字段使用相同的名称。 |
签名 |
所有 | 所有出现在类型或成员签名中的返回类型和参数类型都必须是符合 CLS 的。 |
类型 | ||
基元类型 |
所有 | .NET Framework 类库包括与编译器使用的基元数据类型相对应的类型。这些类型中,以下类型是符合 CLS 的类型:Byte、Int16、Int32、Int64、Single、Double、Boolean、Char、Decimal、IntPtr 和 String。有关这些类型的更多信息,请参见 .NET Framework 类库中的类型表。 |
已装箱的类型 |
所有 | 已装箱的值类型(已转换为对象的值类型)不属于 CLS。请适当改用 System.Object、System.ValueType 或 System.Enum。 |
可见性 |
所有 | 类型和成员声明不能包含比所声明的类型或成员可见性或可访问性差的类型。 |
接口方法 |
Compilers | 当单个类型实现两个接口,而每个接口都需要有具有相同名称和签名的方法定义时,符合 CLS 的语言编译器必须具有用于以上情况的语法。这些方法必须被视为是独特的,并且不需要相同的实现。 |
闭包 |
所有 | 符合 CLS 的接口和抽象类中的单个成员必须都定义成是符合 CLS 的。 |
构造函数调用 |
所有 | 在构造函数访问任何继承的实例数据之前,它必须调用基类的构造函数。 |
类型化的引用 |
所有 | 类型化的引用是不符合 CLS 的。(类型化的引用是一个特殊的构造,它包含一个对对象的引用和一个对类型的引用。类型化的引用使公共语言运行库可以为具有可变数目参数的方法提供 C++ 样式的支持。) |
类型成员 | ||
重载 |
所有 | 允许重载索引属性、方法和构造函数;不能重载字段和事件。
属性不得由类型(即其 getter 方法的返回类型)重载,但允许用不同数目或类型的索引对这些属性进行重载。 只有根据其参数数目和类型,才可以对方法进行重载。 运算符重载不在 CLS 的范围中。但是,CLS 提供了有关提供有用名称(例如 Add())及在元数据中设置位的指南。要支持运算符重载的编译器应该遵循这些指南,但这不是必须的。 |
重载成员的唯一性 |
所有 | 单进行标识符比较,字段和嵌套类型就必须是不同的。(标识符比较后)具有相同名称的方法、属性和事件必须在除返回类型不同之外具有其他不同之处。 |
转换运算符 |
所有 | 如果 op_Implicit 或 op_Explicit 其中之一在其返回类型上重载,则必须有提供转换的替代方法。 |
方法 | ||
重写方法的可访问性 |
所有 | 当重写继承的方法时,除非重写一个从另一个带有 FamilyOrAssembly 可访问性的程序集继承的方法,否则可访问性不能改变。在这种情况下,重写必须具有 Family 可访问性。 |
参数列表 |
所有 | CLS 支持的唯一调用约定就是标准托管调用约定;不允许可变长度参数列表。(使用 Microsoft Visual Basic 中的 ParamArray 关键字和 C# 中的 params 关键字来支持可变数目的参数。) |
属性 | ||
访问器元数据 |
Compilers | 实现属性方法的 getter 和 setter 方法在元数据中标有 mdSpecialName 标识符。 |
访问器可访问性 |
所有 | 属性的可访问性和其访问器的可访问性必须是相同的。 |
修饰符 |
所有 | 属性和其访问器必须同为 static、同为 virtual 或同为 instance。 |
访问器名称 |
所有 | 属性必须遵循特定的命名方式。对于一个名为 Name 的属性,如果定义了 getter 方法,它将叫做 get_Name;如果定义了 setter 方法,它将叫做 set_Name。 |
返回类型和参数 |
所有 | 属性的类型是 getter 的返回类型和 setter 最后一个参数的类型。属性参数的类型是对应于 getter 的参数的类型和 setter 除最后一个参数之外所有参数的类型。所有这些类型都必须符合 CLS,并且不能是托管指针;它们不得被引用传递。 |
事件 | ||
事件方法 |
所有 | 用于添加和移除事件的方法必须同时存在或同时不存在。 |
事件方法元数据 |
Compilers | 实现事件的方法在元数据中必须标有 mdSpecialName 标识符。 |
访问器可访问性 |
所有 | 用于添加、移除和引发事件的方法的可访问性必须相同。 |
修饰符 |
所有 | 用于添加、移除和引发事件的方法必须同为 static、同为 virtual 或同为 instance。 |
事件方法名称 |
所有 | 事件必须遵循特定的命名方式。对于一个名为 MyEvent 的事件,如果定义了 add 方法,它将叫做 add_MyEvent;如果定义了 remove 方法,它将叫做 remove_MyEvent;如果定义了 raise 方法,它将叫做 raise_MyEvent。 |
参数 |
所有 | 添加和移除事件的方法必须分别取一个参数,该参数的类型定义事件的类型,并且该类型必须从 System.Delegate 导出。 |
指针类型 | ||
指针 |
所有 | 指针类型和函数指针类型是不符合 CLS 的。 |
接口 | ||
成员签名 |
所有 | 符合 CLS 的接口要实现不符合 CLS 的方法,应该不需要这些方法的定义。 |
成员修饰符 |
所有 | 符合 CLS 的接口不能定义静态方法,也不能定义字段。允许符合 CLS 的接口定义属性、事件和虚方法。 |
引用类型 | ||
构造函数调用 |
所有 | 对于引用类型,调用对象构造函数仅作为创建对象的一部分,对象只初始化一次。 |
类类型 | ||
继承 |
所有 | 符合 CLS 的类必须从符合 CLS 的类 (System.Object) 继承。 |
数组 | ||
元素类型 |
所有 | 数组元素必须是符合 CLS 的类型。 |
维数 |
所有 | 数组必须具有固定的维数数目,大于零。 |
范围 |
所有 | 数组的所有维数必须具有零下限。 |
枚举 | ||
基础类型 |
所有 | 枚举的基础类型必须是内置 CLS 整数类型(Byte、Int16、Int32 或 Int64)。 |
FlagsAttribute |
Compilers | 枚举的定义中存在 System.FlagsAttribute 自定义属性指示该枚举应该作为一组位域(标志)对待,没有该属性指示该类型应该视为一组枚举常数。建议语言使用 FlagsAttribute 或语言特定的语法两者之一来区分这两种类型的枚举。 |
字段成员 |
所有 | 枚举的 static 字段的类型必须和枚举本身的类型相同。 |
异常 | ||
继承 |
所有 | 引发的对象必须是 System.Exception 类型或从 System.Exception 继承。 |
自定义属性 | ||
值编码 |
Compilers | 要求符合 CLS 的编译器只处理自定义属性(元数据中自定义属性的表示形式)编码的子集。允许出现在这些编码中仅有的几个类型包括:System.Type、System.String、System.Char、System.Boolean、System.Byte、System.Int16、System.Int32、System.Int64、System.Single、System.Double 和所有基于符合 CLS 的基整数类型的枚举类型。 |
元数据 | ||
CLS 遵从性 |
所有 | 其 CLS 遵从性与程序集(这些类型是在该程序集中定义的)的遵从性不同的类型都必须标有此 System.CLSCompliantAttribute。同样,其 CLS 遵从性与其类型的遵从性不同的所有成员也必须进行标记。如果某个成员或类型被标记为不符合 CLS,则必须提供一个符合 CLS 的替换选项。 |