Копировать объект в объект (с помощью Automapper?) - PullRequest
60 голосов
/ 19 апреля 2011

У меня есть класс:

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

У меня есть два экземпляра Person (person1 и person2). Я хотел бы скопировать содержимое person2 в person1. Я хотел бы сделать эту копию в одной инструкции, а свойство не по свойству:

person1.LastName = person2.LastName;

В документе я вижу, как скопировать объект в другой объект, но тип отличается. Как я могу скопировать объект, если тип совпадает?

Ответы [ 4 ]

72 голосов
/ 28 февраля 2013

Как я понимаю вопрос, OP не хочет клонировать person2 в новый экземпляр Person , но спрашивает, как скопировать содержимое person2 в уже существующий экземпляр ( person1 ) из Person . Существует перегрузка метода Mapper.Map в AutoMapper, которая делает это за вас:

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

Примечание 1: @ alexl ответ создает новый экземпляр Person . Если у вас есть другие ссылки на экземпляр, на которые указывает person1 , они не получат (предположительно) нужное обновление данных, если вы перенаправите переменную person1 на новый экземпляр.

Примечание 2: Вы должны знать, что глубина (рекурсивного) копирования зависит от того, какие сопоставления AutoMapper знает в момент сопоставления!
Если член класса Person , скажем, класса Brain и вы дополнительно сделали Mapper.CreateMap<Brain, Brain>(); до вызова копирования данных Mapper.Map<Person, Person>(person2, person1);, то person1 сохранит свой текущий Brain экземпляр, но этот Brain получит значения элементов person2 s Brain . То есть у вас есть глубокая копия .
Но если AutoMapper не имеет сопоставления «мозг-мозг» перед копированием, то элемент person1 Brain будет ссылаться на тот же экземпляр Brain , что и экземпляр person2 ссылки. То есть вы получите мелкую копию .
Это применяется рекурсивно ко всем членам, поэтому вам лучше убедиться, что в AutoMapper есть сопоставления для классов-членов, которые вы хотите глубоко копировать, и нет сопоставлений для классов-членов, которые вы хотите поверхностно копировать.

Альтернативой использованию AutoMapper будет использование подхода с использованием отражения . (Обратите внимание, что код в ссылке делает мелкую копию!)

«Поддержка заполнения существующего объекта вместо того, чтобы AutoMapper создавал сам объект назначения» добавлено в версии AutoMapper 0.2 .

26 голосов
/ 20 апреля 2011

Поскольку вы спросили With Automapper?, могу ли я предложить вам не использовать AutoMapper?

Вместо этого используйте MemberwiseClone() в методе Clone, например

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

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

UPDATE

Важно отметить, что это не приводит к желанию оригинальных плакатов скопировать person1 в person2

Однако (и, как указывает @Jimmy Bogard) использование MemberwiseClone() предпочтительнее, если вам просто нужно сделать копию (клон) объекта.

Например, если вы делаете это:

//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)

тогда действительно вы должны / могли бы использовать

//oh wait, i can just use this!
var person2 = person1.Clone()
17 голосов
/ 19 апреля 2011
Mapper.CreateMap<Person, Person>();

// Perform mapping

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

Надеюсь, это поможет.

2 голосов
/ 19 апреля 2011

Почему вы хотите использовать Automapper для этого?Простой клон сделает всю работу за вас.

Подробнее здесь: Глубокое клонирование объектов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...