首先,让我们来简单地看下什么叫做CLS。
鉴于个人的英文水平,我还是先给出CLS的英文解释,然后我再翻译:
The CLS is a specification that defines the rules to support language integration. This is done in such a way, that programs written in any language (.NET compliant) can interoperate with one another. This also can take full advantage of inheritance, polymorphism, exceptions, and other features.
CLS定义了支持语言继承的规范,他使我们所写的程序可以于任何一门.NET所兼容的语言交互,这使我们也可以充分利用继承,多态,异常以及其他一些特点的优势。
其实简化了说,CLS就是定义了个门语言的子集,从而去保证语言的互操作性。
因此,为了语言之间的互操作,我们应该使我们的程序遵从CLS。
我们看一下系统的层次,系统下应该是程序集,程序集下就是类(或结构体等)。那么我们为了保证语言的互操作性,就应该保证程序集对外的部分都遵从CLS。
这点很容易保证:
当我们新建一个程序集的时候,有一个文件叫做:AssemblyInfo.cs:
[assembly: AssemblyTitle("ClassLibrary1")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("微软中国")] [assembly: AssemblyProduct("ClassLibrary1")] [assembly: AssemblyCopyright("Copyright ? 微软中国 2009")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 使此程序集中的类型 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, // 则将该类型上的 ComVisible 属性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("694543e8-4c7f-4952-9e98-7282ecff1c15")] // 程序集的版本信息由下面四个值组成: // // 主版本 // 次版本 // 内部版本号 // 修订号 // // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
毫无疑问,这里记录的都是当前程序集的信息,那么我们只需要在里面加上一行代码:
[assembly:System.CLSCompliant(true)]
这样程序就保证了整个程序集满足CLS规范。
当我们写一段不满足CLS的程序时:
namespace ClassLibrary1 { public class People { private string name; private uint age; //uint不满足CLS public uint Age { get { return age; } } public People(string name) { this.name = name; } } }
当我们生成程序集的时候,报出了这样的警告:
当然,我再对这个做一些附加的解释,希望不是画蛇添足:
我们都知道,一个程序集存在一些对外的接口,其他的程序集只是与这些对外的接口进行交互,也就是说只要对外的接口满足CLS,这个程序集就可以进行与其他语言的互操作了:
看一个例子,当我们把上述的class People设置为默认的访问修饰符internal时:
class People { private string name; private uint age; //uint不满足CLS public uint Age { get { return age; } } public People(string name) { this.name = name; } }
这个时候,当我生成程序集的时候,并不会报CLS不兼容的错误:
因此,我不想再去说哪些类需要满足CLS。我们只需要记住,如果你写的某个类,或者变量,方法,在程序集可以访问到,那么这个类,方法,变量就需要满足CLS。
当然,有这样一种情况,就是说使用了不满足CLS的方法,变量等会极大提高整个程序的可读性,那么我们就该为这个方法,或者变量等实现一个与其等义的方法等,于是,如果访问该程序集的是同一语言,那么便访问该方法,否则便访问替代方法。
另外,有一种能力叫做取舍。我们不可能做出一个十全十美的项目,人力不允许,物力不允许,精力也不允许,因此,我们必须要放弃一些东西。当我们这个项目基本不太可能与其他语言进行交互时,那么我就没有必要将精力去集中在项目程序集是否满足于CLS上。
当然,如果我们有时间,那么抽出些时间去搞定语言的互操作,还是利大于弊的!