之所以称它是通用的,是因为它对所有 .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(都是限制最大的那个)。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/22353.html