关于CLS如何支持语言互操作性

昨晚和老婆一起学习.N

ET,聊到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.

The CLS (or Common Language Specification) is a simply a contract between programming language designers and class library authors.

CLS是一种规范,如果你用c#写的东西不想被其他语言调用,那么大可不必遵循它,但是如果有时间的话使代码满足CLS总是利大于弊的。

看一段代码:

 

    public class Class1
    {
        
public Class1()
        {
        }

        
public void TestABC()
        {
        }

        
public void Testabc()
        {
        }
    }

 

默认情况下我们可以成功编译以上代码。

现在我们找到工程默认建立的文件AssemblyInfo.cs:

加入一行代码:[assembly:System.CLSCompliant(true)]

重新编译一下,我们会得到一条警告信息:

Warning 1 Identifier 'ClassLibraryCS.Class1.Testabc()' differing only in case is not CLS-compliant D:\PROJECT\TempCollection\ClassLibraryCS\Class1.cs 18 21 ClassLibraryCS

如果此时想从VB中调用TestABC()的话,就会报错,因为VB是大小写不敏感的:

重载决策失败,原因是没有可访问的“TestABC”最适合这些参数:
    'Public Sub Testabc()': 不是最适合
    'Public Sub TestABC()': 不是最适合。

外,只有当类被设计为可能被外部调用的时候才需要考虑满足CLS。如果一个类的修饰符为private的话是不需要考虑CLS的,因为不会有外部的不同语言的类来访问它。

下面是摘录自《c#高级编程》的CLS规范:

那么程序集与CLS兼容有什么要求呢?

       方法原型中的所有类型都必须与CLS兼容。

       数组元素的元素类型必须与CLS兼容。数组中第一个元素的下标必须是0

       CLS兼容类必须继承于CLS兼容类,当然,System.Object是与CLS兼容的。

       CLS兼容类中,方法名是不区分大小写的,两个方法不能仅根据其名称中字母的大小写来区分。

       枚举的类型必须是Int16Int32Int64。其他类型的枚举都是不兼容的。

上述列举的要求只适用于公共成员和受保护的成员。私有方法则无需考虑这些要求,它们可以使用不兼容的类型,而程序集仍然是兼容的。

除了这些要求外,还应遵循更一般的命名约定(详见第2)CLS兼容类不需要严格遵循这些规则,但遵循这些规则会使工作更容易完成。

除了遵循这些命名约定,以支持多种语言外,还必须注意包含类型名称的方法名称。数据类型名是语言所特定的。C#中的intlongfloat 类型等同于VB.NET 中的IntegerLong Single。在方法名中使用数据类型名时,应使用一般的类型名,而不是某语言特定的类型名,即应使用Int32Int64 Single

int ReadInt32();

long ReadInt64();

float ReadSingle();

可以看出,在利用CLS规范和规则进行编译时,很容易创建出可以用于多种语言的组件。

posted @ 2009-06-19 08:30  AdaColor  阅读(304)  评论(0编辑  收藏  举报