web-dev-qa-db-ja.com

オブジェクトをオブジェクトにコピー(Automapperを使用?)

私にはクラスがあります:

public class Person {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Personの2つのインスタンス(person1とperson2)があります。 person2の内容をperson1にコピーします。 1つの命令でnotプロパティごとにこのコピーを作成したいと思います。

person1.LastName = person2.LastName;

ドキュメントでは、オブジェクトを別のオブジェクトにコピーしますが、タイプは異なります。タイプが同じ場合、どのようにオブジェクトをコピーできますか?

61
Kris-I

私は質問を理解しているので、OPはperson2Personの新しいインスタンスに複製したくないが、person2の内容をコピーする方法を求めている既に存在するインスタンスperson1)ofPerson。これを行うAutoMapperのMapper.Mapメソッドのオーバーロードがあります:

Mapper.CreateMap<Person, Person>();
Mapper.Map<Person, Person>(person2, person1);
//This copies member content from person2 into the _existing_ person1 instance.

注1: @alexlの回答は、newPersonのインスタンスを作成します。person1が指すインスタンスへの他の参照がある場合、person1変数を新しいインスタンスにリダイレクトすると、これらは(おそらく)必要なデータ更新を取得しません。

注2:(再帰的な)コピーの深さは、マッピングの時点でAutoMapperがどのマッピングについて知っているかに依存することに注意する必要があります!
PersonクラスのメンバーがクラスBrainであり、コピーデータMapper.CreateMap<Brain, Brain>();呼び出しの前にMapper.Map<Person, Person>(person2, person1);を追加した場合、次にperson1は現在のBrainインスタンスを保持しますが、このBrainperson2Brainのメンバー値を受け取りますインスタンス。つまり、ディープコピーです。
しかし、AutoMapperがコピーする前にBrain-Brainマッピングを持たない場合、person1'sBrainメンバーは同じBrainインスタンスを参照します1つのperson2参照。つまり、浅いコピーを取得します
これはすべてのメンバーに再帰的に適用されるため、AutoMapperには、ディープコピーするメンバークラスのマッピングがあり、浅いコピーするメンバークラスのマッピングがないことを確認することをお勧めします。

AutoMapperを使用する代わりに、 リフレクションを使用するアプローチ を使用することもできます。 (リンク内のコードはshallowコピーを行うことに注意してください!)

「宛先オブジェクト自体をAutoMapperが作成する代わりに、既存のオブジェクトを埋めるサポート」は AutoMapperバージョン0.2で追加 でした。

72
Ulf Åkerstedt
Mapper.CreateMap<Person, Person>();

// Perform mapping

var person1 = Mapper.Map<Person, Person>(person2);

お役に立てれば。

17
alexl

なぜこれにAutomapperを使用したいのですか?単純なクローンがあなたのために仕事をするでしょう。

詳細はこちら: オブジェクトのディープクローニング

2
boena