前言
在.NET Core中,将列表中的某一项赋值给新对象后,更改新对象的某个值,然后发现列表中的数据也发生了变化,该问题主要出在引用的传递上。在C#中,当将一个对象赋值给另一个对象时,实际上是将引用从一个变量复制到另一个变量。这意味着新对象和列表中的原始对象实际上是同一个对象的引用。
如果更改了新对象的某个值,那么实际上是修改了与列表中相同对象的引用的值。这就是为什么原列表中的数据也发生了变化。
为了解决这个问题,需要在将原始对象赋值给新对象时进行深拷贝,而不仅仅是引用复制。这样,新对象将成为一个独立的对象,对其进行的更改不会影响列表中的原始对象。
方法一:AutoMapper
我们可以通过AutoMapper来解决此问题
。AutoMapper 是一个流行的对象映射库,它可以帮助您方便地进行对象之间的映射和复制。
首先,需要将 AutoMapper 添加到您的项目中。您可以通过 NuGet 包管理器或在 .NET Core 项目文件中添加以下引用来完成此操作:
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
</ItemGroup>
一旦您将 AutoMapper 添加到项目中,您可以按照以下步骤使用它来实现深拷贝:
- 定义映射配置:创建一个映射配置,指定如何从原始对象映射到新对象。
using AutoMapper;
// 创建映射配置
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Person, Person>(); // 将 Person 类型映射到自身
});
- 创建映射器:使用配置创建一个映射器对象。
var mapper = new Mapper(config);
- 进行对象映射:使用映射器对象将原始对象映射到新对象。
Person originalPerson = personList[0];
Person newPerson = mapper.Map<Person>(originalPerson);
现在,newPerson
将是 originalPerson
的一个独立副本,对其进行的更改不会影响原始对象。
使用 AutoMapper 可以简化对象之间的映射和复制过程,无需手动编写大量的复制代码。它可以自动处理属性映射和嵌套对象的复制,使代码更简洁和易于维护
方法二:使用JSON序列化和反序列化来实现深拷贝
using System;
using System.Collections.Generic;
using System.Text.Json;
// 假设有一个名为Person的类,其中包含主键和其他属性
class Person
{
public int Id { get; set; }
public string Name { get; set; }
// 其他属性...
}
// 在您的代码中,当需要将列表中的某一项赋值给新对象时,可以使用以下代码来进行深拷贝:
List<Person> personList = new List<Person>();
// 假设您想要将列表中的第一个对象赋值给新对象
Person originalPerson = personList[0];
// 使用JSON序列化和反序列化进行深拷贝
string serializedPerson = JsonSerializer.Serialize(originalPerson);
Person newPerson = JsonSerializer.Deserialize<Person>(serializedPerson);
// 修改新对象的主键
newPerson.Id = 123;
// 现在,列表中的原始对象和新对象是完全独立的,更改新对象的主键不会影响列表中的原始对象
方法三:使用对象的复制构造函数或克隆方法
使用对象的复制构造函数或克隆方法:如果您的对象类实现了复制构造函数或克隆方法,您可以使用该方法来创建新对象的副本。这样,新对象将拥有独立的数据,对其进行的更改不会影响原始对象。
class Person
{
public int Id { get; set; }
public string Name { get; set; }
// 复制构造函数
public Person(Person other)
{
Id = other.Id;
Name = other.Name;
}
// 克隆方法
public Person Clone()
{
return new Person(this);
}
}
// 在您的代码中,可以使用以下方式进行深拷贝:
Person originalPerson = personList[0];
Person newPerson = new Person(originalPerson); // 或者 newPerson = originalPerson.Clone();
newPerson.Id = 123;