WEB开发网
开发学院软件开发C语言 Effective C# 原则27:避免使用ICloneable 阅读

Effective C# 原则27:避免使用ICloneable

 2009-02-19 08:16:19 来源:WEB开发网   
核心提示: public struct ErrorMessage{private int errCode;private int details;private string msg;// details elided}字符串是一个特殊情况,因为它是一个恒定类,Effective C# 原则27:避免

public struct ErrorMessage
{
 private int errCode;
 private int details;
 private string msg;
// details elided
}

字符串是一个特殊情况,因为它是一个恒定类。如果你指定了一个错误消息串,那么所有的错误消息类都引用到同一个字符串上。而这并不会导致任何问题,这与其它一般的引用类型是不一样的。如果你在任何一个引用上修改了msg变量,你会就为它重新创建了一个string对象(参见原则7)。

(译注:string确实是一个很有意思的类,很多C++程序员对这个类不理解,也很有一些C#程序对它不理解,导致很多的低效,甚至错误问题。应该好好的理解一下C#里的string(以及String和StringBulider之间的关系)这个类,这对于学好C#是很有帮助的。因为这种设计思想可以沿用到我们自己的类型中。)

一般情况,如果一个结构中包含了一个任意的引用类型,那么拷贝时的情况就复杂多了。这也是很少见的,内置的赋值语句会对结构进行浅拷贝,这样两个结构中的引用变量就引用到同个一个对象上。如果要进行深拷贝,那么你就必须对引用类型也进行拷贝,而且还要知道该引用类型上是否也支持用Clone()进行深拷贝。不管是哪种情况,你都不用对值类型添加对ICloneable的支持,赋值语句会对值类型创建一个新的拷贝。

一句概括值类型:没有任何理由要给一个值类型添加对ICloneable接口的支持! 好了,现在让我们再看看引用类型。引用类型应该支持ICloneable接口,以便明确的给出它是支持深拷贝还是浅拷贝。明智的选择是添加对ICloneable的支持,因为这样就明确的要求所有派生类也必须支持ICloneable。看下面这个简单的继承关系:

class BaseType : ICloneable
{
 private string _label = "class name";
 private int [] _values = new int [ 10 ];
 public object Clone()
 {
  BaseType rVal = new BaseType( );
  rVal._label = _label;
  for( int i = 0; i < _values.Length; i++ )
   rVal._values[ i ] = _values[ i ];
  return rVal;
 }
}
class Derived : BaseType
{
 private double [] _dValues = new double[ 10 ];
 static void Main( string[] args )
 {
  Derived d = new Derived();
  Derived d2 = d.Clone() as Derived;
  if ( d2 == null )
   Console.WriteLine( "null" );
 }
}

Tags:Effective 原则 避免

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接