我有一个班级:
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
我有两个Person实例(person1和person2)。我想将person2的内容复制到person1。我想在一个指令中创建此副本,并且按属性不属性:
person1.LastName = person2.LastName;
在doc中,我看到将对象复制到另一个对象但类型不同。如何在类型相同时复制对象?
答案 0 :(得分:71)
据我所知,OP不想将 person2 克隆到 Person 的新实例中,而是要求如何复制的内容person2 进入 Person 的 已存在的实例 ( person1 )。 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的答案会创建人的新实例。如果您对 person1 指向的实例有其他引用,则如果将 person1 变量重定向到新实例,则这些引用将无法获得(可能)所需的数据更新。 / p>
注2:您需要注意(递归)复制深度取决于AutoMapper在映射时知道的映射!
如果 Person 类的成员说的是 Brain 类,并且您在复制数据Mapper.CreateMap<Brain, Brain>();
调用之前已经完成了Mapper.Map<Person, Person>(person2, person1);
,那么< em> person1 将保留其当前的 Brain 实例,但此 Brain 将收到 person2 的 Brain的成员值实例。那就是你有一个深层拷贝
但是如果AutoMapper在复制之前没有Brain-Brain映射,那么 person1 的 Brain 成员将引用相同的 Brain 实例作为一个 person2 引用。那就是你会得到一个浅拷贝
这会递归地应用于所有成员,因此您最好确保AutoMapper具有要进行深层复制的成员类的映射,并且没有要进行浅层复制的成员类的映射。
使用AutoMapper的另一种方法是使用an approach using reflection。 (请注意,链接中的代码执行浅复制!)
“支持填充现有对象,而不是AutoMapper创建目标对象本身”是added in AutoMapper version 0.2。
答案 1 :(得分:25)
既然你问With Automapper?
我建议你不要使用AutoMapper吗?
而是在Clone
方法中使用MemberwiseClone()
,例如
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person Clone()
{
return (Person) MemberwiseClone();
}
}
<强>更新强>
重要的是要注意这并没有实现原始海报希望将person1
复制到 person2
然而,如果您只需要制作对象的副本(克隆),则优先使用MemberwiseClone()
(以及@Jimmy Bogard指出)。
例如,如果您这样做:
//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()
答案 2 :(得分:17)
Mapper.CreateMap<Person, Person>();
// Perform mapping
var person1 = Mapper.Map<Person, Person>(person2);
希望这有帮助。
答案 3 :(得分:2)
为什么要为此使用Automapper?一个简单的克隆就能为你完成这项工作。
在此处阅读更多内容:Deep cloning objects
答案 4 :(得分:0)
在当前版本的AutoMapper中,不能使用静态的AutoMapper.Mapper.Map
方法。而是像这样初始化一个新的映射器:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Person, Person>();
});
var mapper = new Mapper(config);
var clone = mapper.Map<Person>(person);
通常,您希望在Startup.cs
文件中注册映射器以进行依赖项注入,并将其注入您的业务类中:
public void ConfigureServices(IServiceCollection services)
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Person, Person>();
});
var mapper = new Mapper(config);
services.AddSingleton(mapper);
// ...
}
重要提示:不要在您的实体类中创建或插入映射器!
当然,在简单的情况下,您应该首选使用MemberwiseClone()
。