通用语言规范 Common Language Specification
CLR 继承了多种语言,并允许不同语言之间的对象能互操作,这是因为 CLR 建立了一套类型,metadata (自描述), 以及通用运行环境的标准。
但是不同的语言之间差异还是相当大,比如有的区分大小写,有的却不;有的支持有的 unsigned 整形值, 运算符重载, 可变的参数数目等等,有的却不。
Microsoft 由此定义了通用语言规范 Common Language Specification (CLS),以此来规定编译器必须支持的特性集合。
CLR/CTS 比 CLS 支持更多的特性,所以如果你不在乎开发语言间的互操作性(比如你的所有项目都采用同一种开发语言),你可以随意使用你选择的开发语言的各种特性。
图 1-6 显示了他们之间的关系
一旦你用一种开发语言定义了一个类型,并且需要再别处用其他开发语言访问该类型,你就必须注意了:该类型必须符合 CLS 规范。以下是在c#中声明一个类型是符合CLS规范的,同时却包含了不符合CLS规范的代码,编译器会提示有错:
using System;
// Tell compiler to check for CLS compliance
[assembly: CLSCompliant(true)]
namespace SomeLibrary
{
// Warnings appear because the class is public
public sealed class SomeLibraryType
{
// Warning: Return type of 'SomeLibrary.SomeLibraryType.Abc()'
// is not CLS-compliant
public UInt32 Abc() { return 0; }
// Warning: Identifier 'SomeLibrary.SomeLibraryType.abc()'
// differing only in case is not CLS-compliant
public void abc() { }
// No warning: this method is private
private UInt32 ABC() { return 0; }
}
}
[assembly:CLSCompliant(true)] 用来告诉编译器公有成员会被其他语言访问,需要确保其符合CLS规范。 CLS 规则的详细信息可参照(http://msdn.microsoft.com/en-us/library/730f1wy3.aspx) 中的 “Cross-Language Interoperability” 小节。
CLR 中一个类型的成员不是字段就是方法,所以你使用到的枚举, 数组, 属性, 索引器, 委托, 事件, 构造函数, 析构函数, 运算符重载, 转换函数等等经过编译器的处理,都成为这两者之一。例如以下的类型定义
using System;
internal sealed class Test
{
// Constructor
public Test() {}
// Finalizer
~Test() {}
// Operator overload
public static Boolean operator == (Test t1, Test t2)
{
return true;
}
public static Boolean operator != (Test t1, Test t2)
{
return false;
}
// An operator overload
public static Test operator + (Test t1, Test t2) { return null; }
// A property
public String AProperty
{
get { return null; }
set { }
}
// An indexer
public String this[Int32 x]
{
get { return null; }
set { }
}
// An event
public event EventHandler AnEvent;
}
编译这些代码后通过 IL Disassembler 工具 (ILDasm.exe) 察看该托管模块(图 1-7),可以发现所有成员都被转变成字段或方法了。
表 1-4 显示了语言之间的映射关系:
成员 | 成员类型 | 对应的程序处理 |
---|---|---|
AnEvent | 字段 | 事件 |
.ctor | 方法 | 构造 |
Finalize | 方法 | 析构 |
add_AnEvent | 方法 | 事件附加方法 |
get_AProperty | 方法 | 属性的读方法 |
get_Item | 方法 | 索引器的读方法 |
op_Addition | 方法 | + 运算 |
op_Equality | 方法 | == 运算 |
op_Inequality | 方法 | != 运算 |
remove_AnEvent | 方法 | 事件移除方法 |
set_AProperty | 方法 | 属性的写方法 |
set_Item | 方法 | 索引器的写方法 |
表 1-4 中未列出的.class, .custom, AnEvent, AProperty, 以及 Item — 这些都是针对该类型的附加 metadata。这些不会被映射成字段或方法,它们只是用来给CLR 或编程语言或工具提供额外的信息。