读 CLR-via-C# 总结之第七章 常量和字段

常量和字段

7.1常量

1.定义常量符号时,它的值必须能在编译时确定,编译器将常量的值保存到程序集的元数据中。这意味着只能为编译器认定的基元类型定义常量。C#也运行定义非基元,前提需要把它的值设置为Null.

  1. 由于常量值从不变化,所以通常被视为静态,为类型定义的一部分,在定义常量时将导致创建元数据。代码引用一个常量符号时,编译器会在定义常量的程序集的元数据查找该符号,提取常量值,并将值嵌入生成的IL代码中。由于常量的值直接嵌入到IL代码中,所以不需要分配内存。在生成了应用程序程序集之后,运行时根本不加载DLL程序集,可以把它从磁盘移除。在修改了常量值之后,DLL程序集需要重新编译,应用程序要获得新值也要重新编译。如果希望在运行时从一个程序集提取另一个程序集的值,那么就不应该使用常量,而是应该使用readonly字段。

7.2 字段

1.字段是一种数据成员,其中容纳了一个值类型或者一个引用类型的引用。字段修饰符有:static,默认(与类型的一个实例相关联),readonly(只能由一个构造器方法中的代码写入),volatile(看到访问这种字段的代码,编译器,CLR或者硬件就不会执行一些”线程不安全”的优化措施)

2.对于类型字段,用于容纳类型字段数据的动态内存是在类型对象中分配的,而类型对象是在类型加载一个AppDomain时创建的,通常在引用了该类型的任何方法首次进行JIT编译的时候,将类型加载到一个AppDomain中。对于实例字段,用于容纳字段数据的动态内存是在构造一个类型实例时创建的。由于字段存储在动态内存中,所以它们的值在在运行时才能获取。字段可以是任何类型,不必像常量一样局限于编译器内置的基元类型。

3.readonly只能在一个构造器方法中写入(构造器只能调用一次,也就是对象首次创建时)编译器和验证机制确保不会被其他方法写入。注意,可以使用反射来修改readonly字段。引用类型被标记为readonly时,那么不可改变的是引用,而非引用的对象。

4.C#实际上,在构造器对对象进行初始化,字段的内联(是指直接赋值来初始化,而不是通过构造器)初始化只是一种语法上的简化。

你可能感兴趣的:(C#学习)