0

別のクラス A から派生したクラス B があります。クラス A は Copy メソッドを実装しています。A.Copy() を利用するクラス B に Copy メソッドを実装するにはどうすればよいですか?

私が Clone を使用していない理由 (おそらく良くない理由) と、この継承構造を持ちたい理由があります。

class A 
{
    ... properties ...
    public A Copy()
    {
        ...copy properties....
    }
}

class B : A 
{
    ... one extra property ...
    public B Copy()
    {
        // how to copy base()??
        ...copy extra propertie....
    }
}
4

4 に答える 4

3

一般的な解決策は、別のインスタンスからすべてのプロパティをコピーするコンストラクターを定義することです。次に、派生クラスは、クラスで定義されたプロパティをコピーし、基本コンストラクターを呼び出して、基本クラスのプロパティをコピーします。

class A 
{
    // properties

    protected A(A other)
    {
        // copy properties
    }

    public A Clone()
    {
        A clone = CloneCore() as A;
        if (clone == null)
            throw new NotImplementedException("Clone Not Implemented Correctly");
        return clone;
    }

    protected virtual object CloneCore()
    {
        return new A(this);
    }
}
class B : A 
{
    // one extra property

    protected B(B other) : base(other)
    {
        // copy extra property
    }

    public new B Clone()
    {
        B clone = CloneCore() as B;
        if (clone == null)
            throw new NotImplementedException("Clone Not Implemented Correctly");
        return clone;
    }

    protected override object CloneCore()
    {
        return new B(this);
    }
}
于 2013-03-22T15:50:56.373 に答える
0

簡単な答え: できません。

A.Copy()型を返すためA、 を返すように変更することはできませんB

オブジェクトには、すべてのフィールドを新しいオブジェクトにコピーするメソッドが既に存在します。と呼ばれていobject.MemberwiseClone()ます。ただし、浅いコピーを実行するため、これには注意してください。(すべての参照型メンバーが既存のオブジェクトを指すことを意味します)。

私が見つけたところによると、通常はディープ コピーが必要ですが、残念ながらこれは、に含めることができるすべてのクラスに「ディープ コピー」メソッドを記述する必要があることを意味しますA

メソッドは通常、ディープ コピーであるClone()と理解されています。(コメントはいつも助けになります)そして、それは戻ってきますobjectBバックが必要な場合は、キャストが必要です。継承されたメソッドの署名を変更できないため、これを回避する良い方法はありません。

newもう 1 つ:関数を定義するときにキーワードを使用しないでください。ポリモーフィズムが壊れ、見つけにくいバグが発生する可能性があります。

public class A : IClonable {
   public ReferenceType member1;
   public int member2;

   public object Clone() {
       var clone = this.MemberwiseClone() as A;  //shallow copy
       clone.CloneReferenceMembers();            //deep copy
       return clone;
   }
   public virtual void CloneReferenceMembers(){
      this.member1 = this.member1.Clone();
   }

}

public class B : A {
   public AnotherReferenceType member3;
   public int member4;

    public override void CloneReferenceMembers(){
       base.CloneReferenceMembers();
       this.member3 = this.member3.Clone();
   }
}
于 2013-03-22T16:29:55.463 に答える
0

親クラスのメンバーにアクセスするために使用されるbaseキーワードを使用できます。

class B : A 
{
    ... extra properties ...
    public B Copy()
    {
        base.Copy();
        ... copy extra properties ...
    }
}
于 2013-03-22T15:49:14.453 に答える