编写符合 CLS 的代码

更新:2007 年 11 月

“公共语言规范”(CLS) 遵从性通常是指有关遵循 CLS 规则和限制的声明。但是,此概念有一个更具体的含义,具体取决于您描述的是符合 CLS 的代码还是符合 CLS 的开发工具(如编译器)。符合 CLS 的工具可以帮助您编写符合 CLS 的代码。

符合 CLS 的代码

如果您要让您的代码符合 CLS,您必须在以下几处以符合 CLS 的方式公开功能:

  • 公共类的定义。

  • 公共类中公共成员的定义,以及派生类(family 访问)可以访问的成员的定义。

  • 公共类中公共方法的参数和返回类型,以及派生类可以访问的方法的参数和返回类型。

在您的私有类的定义中、在公共类上私有方法的定义中以及在局部变量中使用的功能不必遵循 CLS 规则。您还可以在实现您的类的代码中使用任何想要的语言功能并让它仍是一个符合 CLS 的组件。

bhc3fa7f.alert_note(zh-cn,VS.90).gif说明:

交错数组(即数组的数组)符合 CLS。在 .NET Framework 1.0 版中,C# 编译器错误地将其报告为不符合。

您可以使用 CLSCompliantAttribute 将程序集、模块、类型和成员标记为符合 CLS 或不符合 CLS。所有要成为符合 CLS 的程序集都应这样进行标记。未标记为符合 CLS 的程序集将被认为是不符合 CLS 的。如果没有 CLS 属性应用于某个类型,则认为该类型与在其中定义该类型的程序集具有相同的 CLS 遵从性。同样,如果没有 CLS 属性应用于某个成员,则认为该成员与定义该成员的类型具有相同的 CLS 遵从性。如果程序元素中包含的元素未标记为符合 CLS,则不能将此程序元素标记为符合 CLS。本主题结尾的示例阐释了 CLSCompliantAttribute 的使用。

只要满足以下两个条件,即使程序集、模块或类型的某些部分不符合 CLS,这些程序集、模块或类型也可以是符合 CLS 的:

  • 如果元素标记为符合 CLS,则必须使用 CLSCompliantAttribute(同时其参数应设为 false)对不符合 CLS 的部分进行标记。

  • 必须为不符合 CLS 的每个成员提供相当的符合 CLS 的替换成员。

如果您设计一个符合 CLS 的类库,您的库将提供能够同多种编程语言互用的保证;因此,您的库将比不符合 CLS 的版本具有更广泛的客户群。

.NET Framework 提供了一个符合 CLS 的类库。有关该类库的更多信息,请参见 .NET Framework 类库参考

符合 CLS 的工具

面向运行库的语言同意支持 CLS 功能并遵循控制编译器的 CLS 规则。这些语言编译器简化了 CLS 遵从性,使 CLS 数据类型和功能可用于创建组件。以下内容介绍了编译器和其他工具中 CLS 遵从性的级别:

  • 符合 CLS 的使用者工具。

    使用者工具是使开发人员可以访问由符合 CLS 的库提供的所有功能的语言。使用这些语言的开发人员可能不能通过创建新类型扩展符合 CLS 的库,但他们可以使用由符合 CLS 的库定义的任何类型。当您要访问 .NET Framework 类库,但又不需要创作新对象供其他人使用时(例如当您在 ASP.NET 页上使用 Web 窗体或创建 Windows 窗体用户界面时),该级别的遵从性十分有用。

  • 符合 CLS 的扩展者工具。

    扩展者工具是允许开发人员使用和扩展在符合 CLS 的库中所定义类型的语言。开发人员可以使用现有的类型,也可以定义新类型。扩展者工具必须遵循使用者工具必须遵循的所有规则,同时还要遵循一些附加规则,Microsoft Developer Network 网站上的“Common Language Infrastructure, Partition I - Architecture”(公共语言基础结构,第 I 部分 - 体系结构)中描述了这些附加规则。

当您设计自己的符合 CLS 的组件时,使用符合 CLS 的工具将会很有帮助。在没有该支持的情况下编写符合 CLS 的组件将非常困难,因为以别的方式您可能无法访问所有这些要使用的 CLS 功能。

某些符合 CLS 的语言编译器(例如 C# 或 Visual Basic 编译器)使您可以指定您想要代码符合 CLS。这些编译器可以检查 CLS 遵从性并在您的代码使用了不被 CLS 支持的功能时发出提示。C# 和 Visual Basic 编译器允许将程序元素标记为符合 CLS,如果代码不符合 CLS,将导致编译器生成一个编译时错误。例如,下面的代码生成一个编译器警告。

<Assembly: CLSCompliant(True)>

<CLSCompliant(True)> Public Class MyCompliantClass
   Public Sub ChangeValue(value As UInt32)
   End Sub

   Public Shared Sub Main()
      Dim i As Integer = 2
      Console.WriteLine(i)
   End Sub   
End Class
using System;

// Assembly marked as compliant.
[assembly: CLSCompliant(true)]

// Class marked as compliant.
[CLSCompliant(true)]
public class MyCompliantClass {
   // ChangeValue exposes UInt32, which is not in CLS.
   // A compile-time warning results.
   public void ChangeValue(UInt32 value){ }

   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

此代码会生成下面的 C# 警告:

warning CS3001: Argument type 'uint' is not CLS-compliant

或下面的 Visual Basic 警告:

warning BC40028: Type of parameter 'value' is not CLS-compliant.

若要移除该警告,可以指出 ChangeValue 不符合 CLS,如下面的示例所示。

' Assembly marked as compliant.
<Assembly: CLSCompliant(True)>

' Class marked as compliant.
<CLSCompliant(True)> Public Class MyCompliantClass
   ' Method marked as not compliant.
   <CLSCompliant(False)> Public Sub ChangeValue(value As UInt32)
   End Sub

   Public Shared Sub Main()
      Dim i As Integer = 2
      Console.WriteLine(i)
   End Sub   
End Class
using System;

// Assembly marked as compliant.
[assembly: CLSCompliantAttribute(true)]

// Class marked as compliant.
[CLSCompliantAttribute(true)]
public class MyCompliantClass {
   // Method marked as not compliant.
   [CLSCompliantAttribute(false)]
   public void ChangeValue(UInt32 value){ }

   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

此代码不生成编译器警告。输出为 2。

有关如何指定代码 CLS 遵从性的更多信息,请参见您使用的语言编译器的文档。

请参见

概念

语言互用性概述

其他资源

跨语言互操作性