ソースにアクセスできる場合(ここではそうだと思います)、それを絶対に宣言してvirtual
オーバーライドします。ベースClone
を非表示にnew
するのは悪い考えかもしれません。で動作していることを知らないコードがある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!