2012-12-31 50 views
3

假設我有一個類ABA派生:Cloneable的在派生類

class A : ICloneable 
{ 
    public object Clone() {...} 
} 

class B : A, ICloneable 
{ 
    public object Clone() {...} 
} 

這給

'B.Clone()' hides inherited member 'A.Clone()'. Use the new keyword if hiding was intended. 

警告。

(1)建議的方式是什麼?使用new或聲明A.Clone()virtualoverride in B

(2)如果在A一些成員和A.Clone()正確克隆,有一個簡單的方法來克隆它們在B.Clone()或做我必須明確地克隆他們B.Clone()也?

回答

7

如果您有權訪問您的源代碼(我猜是這裏的情況),那麼絕對聲明它爲virtual並覆蓋它。如果隱藏基地Clonenew可能是一個壞主意。如果任何代碼不知道它與B一起工作,那麼它將觸發錯誤的克隆方法並且不返回適當的克隆。

關於物業轉讓,可能考慮實施的拷貝構造函數,並且每個級別可以處理自己的克隆:

public class A : ICloneable 
    { 
     public int PropertyA { get; private set; } 

     public A() 
     { 

     } 

     protected A(A copy) 
     { 
      this.PropertyA = copy.PropertyA; 
     } 

     public virtual object Clone() 
     { 
      return new A(this); 
     } 
    } 

    public class B : A, ICloneable 
    { 
     public int PropertyB { get; private set; } 

     public B() 
     { 

     } 

     protected B(B copy) 
      : base(copy) 
     { 
      this.PropertyB = this.PropertyB; 
     } 

     public override object Clone() 
     { 
      return new B(this); 
     } 
    } 

每個副本構造函數調用基複製構造函數傳遞本身環比下滑。每個繼承級別直接複製屬於它的屬性。

編輯:如果您使用new關鍵字來隱藏基本實現,下面是可能發生的一個示例。與樣品實現(在它的臉看起來罰款)

public class A : ICloneable 
{ 
    public int PropertyA { get; protected set; } 

    public object Clone() 
    { 
     Console.WriteLine("Clone A called"); 
     A copy = new A(); 
     copy.PropertyA = this.PropertyA; 
     return copy; 
    } 
} 

public class B : A, ICloneable 
{ 
    public int PropertyB { get; protected set; } 

    public new object Clone() 
    { 
     Console.WriteLine("Clone B called"); 
     B copy = new B(); 
     copy.PropertyA = this.PropertyA; 
     copy.PropertyB = this.PropertyB; 
     return copy; 
    } 
} 

但是當你使用它:

B b = new B(); 
A a = b; 
B bCopy = (B)a.Clone(); 
//"Clone A called" Throws InvalidCastException! We have an A!