现在的位置: 首页 > 综合 > 正文

通用类型系统

2012年11月25日 ⁄ 综合 ⁄ 共 1970字 ⁄ 字号 评论关闭

      现在, 你应该知道CLR的所有内容都是围绕类型展开的, 类型给你的应用程序和其他类型提供了所需要的功能. 类型也作为一种机制使得一种语言编写的代码可以和另一种语言编写的代码进行无缝地集成. 因为类型是CLR的根基, 微软创建了正式的文档说明——通用类型系统(CTS)——来表述类型是如何定义的, 以及它们的行为是什么样的.

      >>注意: 实际上, 微软已经将CTS和.NET Framework的其他方面提交给ECMA来形成标准, 包括文件格式, metadata, IL, 访问下面的平台(P/Invoke), 这个标准被称为通用语言架构(Common Language Infrastructure, CLI). 此外, 微软也提交了部分FCL, C#编程语言, 和C++/CLI编程语言. 关于这些工业标准的信息, 请到ECMA的网站上参考www.ecma-international.org/memento/TC39.htm

     CTS规范规定一个类型可以包含零个或者多个成员:

Ÿ   字段: 一个数据变量, 是对象状态的一部分, 字段是通过它们的名字和类型标识的.

Ÿ   方法: 对对象进行操作的函数, 通常会改变对象的状态. 方法有一个名字, 签名和一些修饰符. 签名规定了参数的数量以及次序, 参数的类型, 函数是否有返回值, 如果有返回值, 函数返回值的类型也是签名的一部分.

Ÿ   属性: 对调用者来说, 这个成员看起来像一个字段, 但是对类型实现者来说, 它看起来像一个方法(或者两个方法). 属性允许实现者在访问属性值和/或计算属性值之前验证输入参数和对象的状态. 它还允许类型的用户使用简单的语法. 最后, 属性允许你创建只读或者只写的字段.

Ÿ   事件: 事件允许对象之间实现通知的机制, 例如, 一个按钮可以提供一个事件来通知其他对象按钮被点击了.

CTS也规定了类型可见性和访问类型的成员的规则, 例如, 标记一个类型为public将会使其在任何的程序集中都是可见的. 另一方面, 标记一个类型为assembly(在C#中成为internal)将会使其尽在相同的程序集中可见. 因此CTS制定了规则, 程序集构成了类型可见性的边界, CLR实施这些可见性规则.

一个类型对于掉用者是可见的可以进一步地限制掉用户则访问类型成员的能力. 下面的列表给出了控制访问成员的有效的选项:

Ÿ   Private: 方法只能被该类型的其他函数调用.

Ÿ   Family: 方法被派生类型调用, 不管它们是否在一个程序集中, 注意很多语言(例如C++和C#)将family称为protected.

Ÿ   Family and assembly: 方法被派生类型调用, 但是要求派生类型定义与基类型在相同的程序集中. 很多语言(例如C#和VB)没有提供这个访问控制, 当然IL程序集语言有这种控制.

Ÿ   Assembly: 方法被相同程序集中的任何代码调用, 很多语言称其为internal.

Ÿ   Family or assembly: 方法被任何程序集中的派生类型调用, 也能被相同程序集中的任何类型调用. C#将其称为protected internal.

Ÿ   Public: 方法能被任何程序集中的任何代码调用.

      此外, CTS定义了控制类型继承, 虚函数, 对象生命周期等规则, 这些规则的定义是为了在现代编程语言中提供语义上的表达. 实际上, 你不必学习CTS规则, 因为你选择的语言会给出它自己的编程语言语法和类型规则, 而且你比较熟悉这些规则, 它会在编译器间产生程序集的时候, 将特定语言的语法映射到IL——CLR的语言.

      当我第一次使用CLR的时候, 我很快意识到最好认为编程语言和你的代码的行为是两个不同的事情. 使用C++, 你可以定义你自己的类型, 以及它们的成员. 当然, 你可能使用过C#或者VB定义了相同的类型, 以及相同的成员. 确实, 定义类型的语法是不同的, 这依赖于你所选择的语言, 但是类型的行为绝对是相同的, 因为CLR的CTS规定了类型的行为.

      为了帮助澄清这个思想, 让我给你举个例子, CTS允许一个类型只能派生自一个基类, 所以当C++语言支持类型从多个基类继承时, CTS不能接受这样的派生类型. 为了帮助开发者, 微软的C++/CLI编译器会报错, 如果它检测到你企图创建托管的代码, 其包含着派生自多个基类的类型.

      这是CTS的另一个规则. 所有的类型必须从一个预定义的类型继承: System.Object. 正像你看到的, Object是System名字空间中的类型名字, 它是所有其他类型的根, 因此保证了每个类型都至少有一组行为. 特别地, System.Object类型允许你做如下的事情:

  • Ÿ   比较两个实例是否相等
  • Ÿ   获得一个实例的hash编码
  • Ÿ   查询一个实例的真实类型
  • Ÿ   对一个实力执行浅拷贝(按位拷贝)
  • Ÿ   获得实例对象当前状态的字符串表示

抱歉!评论已关闭.