首页 > 编程笔记 > C#笔记

C#/.NET公共类型系统(CTS)

公共类型系统(Comnioii Type System, CTS)定义了什么是类型,以及每个类型可以拥有的成员和行为。

之所以称它是通用的,是因为它对所有 .NET 语言都适用。CTS 是保证 C# 语言类型安全的前提。

前边已经说过,CTS 只是一个规范,并没有限制它的实现方式。CLR 可以看作是 CTS 的一种实现,它符合上面给出的链接上的所有要求。其他的实现包括 Mono, Rotor 等。

下表列出了 .NET 中一些基础名词及缩写,以及这些名词之间的相互关系。

名词 说明
VES(虚拟执行系统) 负责为某种语言在执行时提供一切必须的上下文和内存、线程管理、字符串驻 留、垃圾回收、即时编译等服务。CLR 是它的一个实现。可以用运行时(Runtime)代称。一个 VES 的实现可以提供上面所说的所有服务,也可以只提供部分服务
IL(中间语言)  .NET 框架语言第一步编译的目标语言。它会再通过 JIT 编译器编译为机器码
CTS(公共类型系统) CLI 的一部分,描述了各种类型应该具有怎样的行为以及可以拥有什么样的成员
CLS(公共语言规范) CTS 的一部分,描述了一个框架语言需要拥有的最小功能集
CLI(公共语言基础设施) 上面所有的汇总。它包括了 VES、IL、CTS、CLS的定义,还规定了元数据应该包括什么等等。目前,主流的 CLI 实现有 .NET 编译器、微软 XNA、Rotor (即 Shared Source CLI)等等。可以在 ECMA334 和 ECMA335 这两份文件中找到 CLI 的全部内容

类型指的是集合{类,结构,接口,枚举,委托}中的任意一个成员。

类型(type)和 类(class)不同,后者是前者的一个特殊情况。

任何拥有某类型的值(value)称为某类型的一个实例(instance)。

在 .NET 中,对任何值的使用(作为参数传递或操作)都需要首先明确这个值的类型是什么。

接口和委托都是一种特殊的类,而结构可以看作一个轻量级的类。

类型可以被分为值类型(结构和枚举)以及引用类型(类、接口、指针、.字符串、委托、数组),没有第三种情况。特别的,指针属于引用类型。

类型可以拥有 0 或多个成员,这些成员可以简单地分为字段、方法和嵌套类型。

字段成员包括:

1) 常量(const)

一个隐式为静态和只读的成员。由于它一定是静态的,所以它属于类 型本身。

2) 字段(field)和属性(property)

刻画类型的基本性质。静态的字段和属性属于类型本身。

属性还分为无参属性和有参属性(索引器),并包括两个方法。

3) 事件(event)

事件在对象以及其他相关对象之间实现了一个通知机制。

例如,利用按钮提供的一个事件,可以在按钮被单击之后通知其他对象。

实际上也可以将其看作一种方法,只不过不能自定义。

其中,属性和事件自带的方法位于附加的元数据中,无法自定义和修改。

方法成员包括:

1) 构造函数(constructor)和析构函数(destructor)

用于类型初始化和类型的垃圾回收。 构造函数又可以分为静态的和实例的。

2) 方法(method)

类型的方法可以视为它提供的功能,分为静态的和实例的。

3) 操作符重载

一种特殊的方法,它用于重写操作符的定义。

可以在类型中定义其他类型,这称为嵌套类型。例如,类中可以含有委托和另一个类。不过,嵌套类型的使用有很多限制。

CTS 也规定了某些类型只能拥有上述成员的一小部分而不是全部。例如,枚举类型不可以拥有自己的方法,属性和事件。

C# 支持 6 种类型访问修饰符。访问范围由大到小排序为:

1) public:没有限制。

2) protected internal:只能在所在程序集、定义的类型或派生类型进行访问。

3) internal:只能在所在程序集访问。

4)  private protected: C# 7.2 新增的访问修饰符,等同于5和6中满足任意一个。

5) protected:只能由定义的类型或派生类型进行访问。

6) private:只能由定义的类型进行访问。

所有修饰符都可以修饰类型成员,而对应于直接定义在命名空间下面的类型,则只有 public 和 internal 是可以使用的(除非类型嵌套于另一个更大的类型中)。

显然,为一个非嵌套类加上 private 和 protected 是毫无意义的。

所以,除了 public 和 internal,其他四种修饰符不能作用于非嵌套类。

由 internal 修饰的类中的方法只能被同程序集的其他对象访问。

如果一个程序集 A 中有一个 internal 的类型 B,它含有方法 C,那么程序集 D 中的代码不能调用方法 C,即使 C 是 public 的。

因为类型 B 对于程序集 D 不可见。程序集 D 也可以定义自己的类型 B,它被视为和程序集 A 中的 B 不同。

类型的访问修饰符体现了封装性,即开发者可以控制类型中哪些方法和成员对外界是否可见,从而令外界不需要知道它们永远不会访问或调用的成员。

如果没有指定访问修饰符,类型的访问修饰符默认为 internal,类型成员则默认为 private(都是限制最大的那个)。

所有教程

优秀文章