web-dev-qa-db-fra.com

Copier objet à objet (avec Automapper?)

J'ai un cours:

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

J'ai deux instances de Personne (personne1 et personne2). Je voudrais copier le contenu de person2 vers person1. Je voudrais faire cette copie en une seule instruction et pas propriété par propriété:

person1.LastName = person2.LastName;

Dans la doc, je vois copier un objet vers un autre objet mais le type est différent. Comment copier l'objet lorsque le type est le même?

61
Kris-I

Si je comprends bien la question, OP ne veut pas cloner person2 dans une nouvelle instance de Person, mais demande comment copier le contenu de person2 dans une instance déjà existante ( person1 =) de Personne. Il y a une surcharge de la méthode Mapper.Map d'AutoMapper qui fait cela pour vous:

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

Remarque 1: La réponse de @ alexl crée une instance new de Person. Si vous avez d'autres références à l'instance vers laquelle pointe person1, celles-ci n'obtiendront pas (vraisemblablement) la mise à jour des données souhaitée si vous redirigez la variable person1 vers une nouvelle instance.

Remarque 2: Vous devez savoir que la profondeur de copie (récursive) dépend des mappages qu'AutoMapper connaît au moment du mappage!
Si un membre de la classe Person est de la classe Brain et que vous avez en plus fait Mapper.CreateMap<Brain, Brain>(); avant le copier les données Mapper.Map<Person, Person>(person2, person1); call, puis person1 gardera son instance Brain actuelle mais cette Brain sera recevoir les valeurs membres de person2 s Brain instance. C'est-à-dire que vous avez une copie profonde .
Mais si AutoMapper n'a pas de mappage Brain-Brain avant la copie, alors person1's Brain membre fera référence au même Brain comme référence person2. Autrement dit, vous obtiendrez une copie peu profonde .
.

Une alternative à l'utilisation d'AutoMapper serait d'utiliser ne approche utilisant la réflexion . (Notez que le code dans le lien fait une copie peu profonde!)

"Prise en charge du remplissage d'un objet existant, au lieu que AutoMapper crée lui-même l'objet de destination" était ajouté dans AutoMapper version 0.2 .

72
Ulf Åkerstedt

Puisque vous avez demandé With Automapper?, Puis-je vous suggérer de ne pas utiliser AutoMapper?

Utilisez plutôt MemberwiseClone() dans une méthode Clone, par exemple.

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

    public Person Clone()
    {
        return (Person) MemberwiseClone();
    }
}

[~ # ~] mise à jour [~ # ~]

Il est important de noter que cela n'atteint pas le désir des affiches originales de copier person1 dansperson2

Cependant, (et comme le souligne @Jimmy Bogard), l'utilisation de MemberwiseClone() est préférable si vous avez juste besoin de faire un copier (clone) de l'objet.

Par exemple, si vous faites cela:

//I need a copy of person1 please! I'll make a new person object 
//and automapper everything into it!
var person2 = new Person2();
Mapper.Map<Person, Person>(person1, person2)

alors vraiment vous devriez/pourriez utiliser

//oh wait, i can just use this!
var person2 = person1.Clone()
26
wal
Mapper.CreateMap<Person, Person>();

// Perform mapping

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

J'espère que cela t'aides.

17
alexl

Pourquoi voulez-vous utiliser Automapper pour cela? Un simple clone ferait le travail pour vous.

En savoir plus ici: Objets de clonage profond

2
boena