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

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

 2009-02-19 08:16:19 来源:WEB开发网   
核心提示: 如果你运行这个程序,你就会发现d2为null,Effective C# 原则27:避免使用ICloneable(3),虽然Derived是从BaseType派生的,但从BaseType类继承的Clone()函数并不能正确的支持Derived类:它只拷贝了基类,应该创建一个受保护的构造函数,

如果你运行这个程序,你就会发现d2为null。虽然Derived是从BaseType派生的,但从BaseType类继承的Clone()函数并不能正确的支持Derived类:它只拷贝了基类。BaseType.Clone()创建的是一个BaseType对象,不是派生的Derived对象。这就是为什么程序中的d2为null而不是派生的Derived对象。即使你克服了这个问题,BaseType.Clone()也不能正确的拷贝在Derived类中定义的_dValues数组。一但你实现了ICloneable, 你就强制要求所有派生类也必须正确的实现它。实际上,你应该提供一个hook函数,让所有的派生类使用你的拷贝实现(参见原则21)。在拷贝时,派生类可以只对值类型成员或者实现了ICloneable接口的引用类型成员进行拷贝。对于派生类来说这是一个严格的要求。在基类上实现ICloneable接口通常会给派生类添加这样的负担,因此在密封类中应该避免实现ICloneable 接口。

因此,当整个继承结构都必须实现ICloneable时,你可以创建一个抽象的Clone()方法,然后强制所有的派生类都实现它。

在这种情况下,你需要定义一个方法让派生类来创建基类成员的拷贝。可以通过定义一个受保护的构造函数来实现:

class BaseType
{
 private string _label;
 private int [] _values;
 protected BaseType( )
 {
  _label = "class name";
  _values = new int [ 10 ];
 }
 // Used by devived values to clone
 protected BaseType( BaseType right )
 {
  _label = right._label;
  _values = right._values.Clone( ) as int[ ] ;
 }
}
sealed class Derived : BaseType, ICloneable
{
 private double [] _dValues = new double[ 10 ];
 public Derived ( )
 {
  _dValues = new double [ 10 ];
 }
 // Construct a copy
 // using the base class copy ctor
 private Derived ( Derived right ) :
  base ( right )
 {
  _dValues = right._dValues.Clone( )
   as double[ ];
 }
 static void Main( string[] args )
 {
  Derived d = new Derived();
  Derived d2 = d.Clone() as Derived;
  if ( d2 == null )
   Console.WriteLine( "null" );
 }
 public object Clone()
 {
  Derived rVal = new Derived( this );
  return rVal;
 }
}

基类并不实现ICloneable接口; 通过提供一个受保护的构造函数,让派生类可以拷贝基类的成员。叶子类,应该都是密封的,必要它应该实现ICloneable接口。基类不应该强迫所有的派生类都要实现ICloneable接口,但你应该提供一些必要的方法,以便那些希望实现ICloneable接口的派生类可以使用。

ICloneable接口有它的用武之地,但相对于它的规则来说,我们应该避免它。对于值类型,你不应该实现ICloneable接口,应该使用赋值语句。对于引用类型来说,只有在拷贝确实有必要存在时,才在叶子类上实现对ICloneable的支持。基类在可能要对ICloneable 进行支持时,应该创建一个受保护的构造函数。总而言之,我们应该尽量避免使用ICloneable接口。

上一页  1 2 3 

Tags:Effective 原则 避免

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