一 常量与字段

(一) 常量

  常量总是被视为静态成员,而不是实例成员。定义常量将导致创建元 数据。代码引用一个常量时,编译器会在定义常量的程序集的元数据中查找该符号,提取常量的值,并将值嵌入IL中。由于常量的值直接嵌入IL,所以在运行时 不需要为常量分配任何内存。此外,不能获取常量的地址,也不能以传递引用的方式传递常量。这些限制意味着,没有很好的跨程序集版本控制特性。因此,只有在 确定一个符号的值从不变化时,才应该使用。如果希望在运行时从一个程序集中提取一个程序集中的值,那么不应该使用常量,而应该使用 readonly 字段。

(二) 字段

  CLR支持类型字段和实例字段。对于类型字段,用于容纳字段数据 的动态内存是在类型对象中分配的,而类型对象是在类型加载到一个AppDomain时创建的;对于实例字段,用于容纳字段数据的动态内存则是在构造类型的 一个实例时分配的。字段解决了版本控制问题,其值存储在内存中,只有在运行时才能获取。

 

  如果字段是引用类型,且被标记为readonly,那么不可改变的是引用,而非字段引用的对象。

 

(三) 常量与只读字段的区别

 

  readonly和const本质上都是常量,readonly是运行时常量而const是编译期常量。两种常量具有以下区别:

 

  • 编译期常量的值在编译时获得,而运行时常量的值在运行时获得。
  • 两者访问方式不同。编译期常量的值是在目标代码中进行替换的,而运行时常量将在运行时求值,引用运行时常量生成的IL将引用到readonly的变量,而不是变量的值。因此,编译期常量的性能更好,而运行时常量更为灵活。
  • 编译期常量仅支持整型、浮点型、枚举和字符串,其它值类型如DateTime是无法初始化编译期常量的。然而,运行时常量则支持任何类型。
  • 编译期常量是静态常量,而运行时常量是实例常量,可以为类型的每个实例存放不同的值。

 

  综上所述,除非需要在编译期间得到确切的数值以外,其它情况,都应该尽量使用运行时常量。

 

(四) 常量与字段的设计

 

  • 不要提供公有的或受保护的实例字段,应该始终把字段定义为private。
  • 要用常量字段来表示永远不会改变的常量。
  • 要用公有的静态只读字段定义预定义的对象实例。
  • 不要把可变类型的实例赋值给只读字段。

 

posted on 2013-11-01 16:51  zzunstu  阅读(163)  评论(0编辑  收藏  举报