结构设计

结构是值类型。结构是在堆栈上或以内联方式分配的,当结构超出范围时将被释放。通常情况下,值类型的内存空间分配和释放的开销较小;但在需要大量装箱和取消装箱操作的方案中,值类型的执行性能较引用类型要差。有关更多信息,请参见装箱和取消装箱(C# 编程指南)

有关值类型和引用类型的更多信息,请参见通用类型系统概述

不要为结构提供默认的构造函数。

如果某一结构定义了默认构造函数,则在创建该结构的数组时,公共语言运行库会自动对每个数组元素执行该默认构造函数。

有些编译器(如 C# 编译器)不允许结构拥有默认构造函数。

对值类型实现 System.IEquatable`1。

在确定两个值类型是否相等时,IEquatable 要优于 Equals。通过使用接口,调用方可避免装箱和托管反射的不良性能影响。

确保所有实例数据均设置为零、false 或 null(根据需要)的状态是无效的。

如果遵循这一准则,新构造的值类型实例不会处于不可用的状态。例如,下面的结构的设计是错误的。参数化构造函数有意确保存在有效的状态,但在创建结构数组时不执行该构造函数。这意味着实例字段 label 初始化为 null(在 Visual Basic 中为 Nothing),这对于此结构的 ToString 实现是无效的。

   1: public  struct BadStructure 
   2: {
   3:     string label;
   4:     int width;
   5:     int length;
   6:     
   7:     public BadStructure (string labelValue, int widthValue, int lengthValue) 
   8:     {
   9:         if (labelValue == null || labelValue.Length ==0) 
  10:         {
  11:             throw new ArgumentNullException("label");
  12:         }
  13:         label = labelValue;
  14:         width = widthValue;
  15:         length = lengthValue;
  16:     }
  17:     
  18:     public override string ToString() 
  19:     {
  20:         // Accessing label.Length throws a NullReferenceException
  21:         // when label is null.
  22:         return String.Format("Label length: {0} Label: {1} Width: {2} Length: {3}",
  23:             label.Length, label, width,length);
  24:     }
  25: }
  26:  

在下面的代码示例中,GoodStructure 的设计对 label 字段的状态未作任何假定。ToString 方法设计为处理 null 标签。

   1: public  struct GoodStructure 
   2: {
   3:     string label;
   4:     int width;
   5:     int length;
   6:     
   7:     public GoodStructure (string labelValue, int widthValue, int lengthValue) 
   8:     {
   9:         label = labelValue;
  10:         width = widthValue;
  11:         length = lengthValue;
  12:     }
  13:     
  14:     public override string ToString() 
  15:     {
  16:         // Handle the case where label might be 
  17:         // initialized to null;
  18:         string formattedLabel = label;
  19:         int formattedLableLength;
  20:         if (formattedLabel == null)
  21:         {
  22:             formattedLabel = "<no label value specified>";
  23:             formattedLableLength = 0;
  24:         } else
  25:         {
  26:             formattedLableLength = label.Length;
  27:         }
  28:         return String.Format("Label Length: {0} Label: {1} Width: {2} Length: {3}",
  29:             formattedLableLength, formattedLabel, width, length);
  30:     }
  31: }
posted @ 2010-04-01 00:00  Gang.Wang  阅读(266)  评论(0编辑  收藏  举报