2016-12-07 1 views
4

をクローニングし、私のオブジェクトを一般簡素化タイプFloatCommandのオブジェクトをdeepcopyするためにC#が、おそらく私は方法を書いた方法

_tCheckinCommand = _pTCommand.DeepCopy(stagingLocHeadDto, SCICommand, 
    new List<FloatProductDetailsDTO>(_pTCommand.MoveProducts)); 

MemberwiseClone()は保護されたメソッドなので、上記のように呼び出す必要があります。たとえば、メソッドパラメータのFloatCommand型で解析できず、fc.MemberwiseClone()などで呼び出すことはできません。私のメソッドはFloatCommand型で動作する必要があるため、FloatCommandから継承する新しいネストされたクラスCopyableFloatCommandを作成しました。 DeepCopyメソッドは、FloatCommandを浅くクローン化し、子タイプにキャストし、必要に応じて/としていくつかのプロパティを変更します。

この目的のために特別に新しいクラスを作成するのはちょっと大変なようですが、私はその時点でより明白な方法を書いていませんでした。ラインオブコードの面では、上記のようなディープコピーを使用する簡単な方法がありますか? UserCommandという別のクラスがUserオブジェクトをディープコピーしようとするとどうでしょうか? UserComandは、両方ともCommandから継承するように、FloatCommandの兄弟になります。異なるサブタイプにはわずかに異なるプロパティがあるため、メソッドは異なるタイプのパラメータを解析します(ただし、パラメータをすべて削除して、必要に応じてインスタンス変数を使用できます)。

上記の制約条件で、コードの重複を避けるために、すべてのコマンドタイプのアクセスにDeepCopyメソッドを書き込む、より一般的な方法があります。

ありがとうございます!

+0

あなたはAutoMapperを知っていますか? –

+0

@MatíasFidemraizer私はそうです。しかし、AutoMapperは "オブジェクトBをオブジェクトBにクローンし、その違いをどうするかを選択する"のようなものがありますが、本質的に "オブジェクトAをオブジェクトAに複製する"ことをするのは面倒だったように、参照リストから削除しました。私は本当に価値があると思うところです。 – notsoobvious

+1

車輪を再発明することが余計に残っているかどうかはわかりません。 AutoMapperができることの10%を使っているかもしれませんが、あなたはまだ時間を節約し、他の問題に集中してください。 –

答えて

1

私はあなたがオブジェクトを複製し、クローン化した後にその状態を変更する責任が分離されるべきだと思っていると思います。あなたは同様のタスク(私はUserCommandを意味します)に直面しているからです。私はこのような状況で、次の操作を行います

変異インターフェイスを作成します。

public interface ICopyCommandMutation 
{ 
    void Mutate(Command target); 
} 

extensabilityさのために私は、デフォルトのmuateの実装作成します。作成

public class NoMutation : ICopyCommandMutation 
{ 
    public void Mutate(Command target) {} 
} 

をCopyableCommandクラスを開き、そこにDeepCopy()メソッドを移動します(CopyableCommandからFloatCommandも継承する必要があります)。

public CopyableCommand : Command 
{ 
    public CopyableCommand DeepCopy(ICopyCommandMutation commandMutation = null) 
    { 
     var newCommand = (CopyableCommand)MemberwiseClone(); 
     if (commandMutation == null) commandMutation = new NoMutation(); 
     commandMutation.Mutate(newCommand); 
     return newCommand; 
    } 
} 

これで、すべてのCopyableCommand継承者を 'mutations'でコピーできます。クラスを実装するだけで済みます。たとえば、あなたの質問からFloatCommand「変異」:ここでは

public class ChangeLocationRecountProducts : ICopyCommandMutation 
{ 
    // these fields should be initialized some way (constructor or getter/setters - you decide 
    LocationHeaderDTO locHeader; 
    string commandId; 
    List<FloatProductDetailsDTO> recountProducts; 

    public void Mutate(Command floatCommand) 
    { 
    var fc = floatCommand as FloatCommand; 
    if (fc == null) { /* handle problems here */ } 
    fc.Location = locHeader ?? fc.Location; 
    fc.CommandId = commandId ?? fc.CommandId; 
    fc.RecountProducts = recountProuducts ?? fc.RecountProducts; 
    } 
} 

が用法である:あなたがUserCommand「を変異させる」する必要がある場合

var clrp = new ChangeLocationRecountProducts(); 
// ... setting up clrp 
_tCheckinCommand = _pTCommand.DeepCopy(clrp); 

は今 - あなたはそれのために別々の突然変異クラスを行うことができますそこに突然変異の論理を保つ。異なる突然変異で異なる突然変異を作る能力は、(別々の突然変異クラスを定義するだけで)自由になる。 私がここで見ることができる唯一の問題は、あなたはおそらくCopyableCommandを作成し、それから他のコマンド(サードパーティのライブラリですか?)を継承することができないということです。解決策は、キャッスル動的プロキシを使用することです。

私はAutomapperを使用していませんが、私はそれが似たようなことをしていると思われます。

解決策は「コードライン最適化」ではありませんが、インスタンスのコピー時に多数のコマンドクラスを変更する必要がある場合は、その利点があります。

+0

まだ試したことはありませんが、努力と奥行き/詳細あなたの応答の。ありがとうございます! – notsoobvious

関連する問題