<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 
           明辨值类型和引用类型的使用场合:

Bill Wagner 先生给了一个原则:

值类型用于存储数据,引用类型用于定义行为。

判断第一个原则的适用性有以下四个问题

 

     1.该类型的主要职责是否用于数据存储?
 
  2.该类型的公有接口是否都是一些存取属性?

  3.是否确信该类型永远不可能有子类?

  4.是否确信该类型永远不可能具有多态行为?

 

另一个原则应该是 值类型用于和非托管打交道,引用类型用于和托管打交道。

1.由于值类型实例在栈和托管堆之间的转换而导致的box/unbox,以及由此带来的托管堆上的垃圾。

  2.值类型默认情况下采用的是值拷贝语义,如果是比较大的值类型,在传递参数和函数返回值时,同样会带来性能问题。

第一条的解释:

值类型的装箱和取消装箱过程中,

装箱 生成了一个引用型的副本 造成托管堆上的垃圾

Bill Wagner在本条款中提到了引用类型会给垃圾收集器带来负担这个表面看似正确的判断。但是由于box/unbox的效应,有些情况下,反倒是值类型给垃圾收集器带来了更多的负担。比如将一些值类型放到一个集合中,然后又频繁地对其进行读写操作。如果碰到这种情况,我想放弃结构而采用类未尝不是一种更好的做法。事实上,将一个用作数据存储的值类型(比如System.Drawing.Point)添加到一个集合(System.Collections.ArrayList)中是一个太常见不过的操作。

第二条

 “尽量使用pass-by-reference(传址),少用pass-by-value(传值)
.NET框架的Design Guidelines for Class Library Developers文档中,在说明什么时候应该使用结构类型的时候,其中提到了一项原则(还有其他一些并行原则)——类型实例数据的大小要小于16个字节。该文档主要是从类型的运行效率层面来考虑的

 

 从上述两条讨论来看,我个人倾向于对结构类型采取更为保守的设计策略。而对于类则可以积极大胆地使用。因为将结构类型不适当地设计为类带来的不良后果要远远小于将类不适当地设计为结构类型所带来的不良后果。就目前的经验来看,我甚至认为只有和非托管互操作打交道的情况才是使用结构类型最充足的理由,其他情况都要三思而后行。当然,在C# 2.0中引入泛型技术之后,box/unbox将不再是一个沉重的负担,应付一些非常轻量级的场合,结构类型依然有自己的一席之地。