C# 为什么列表的副本仍然使用C更改原始列表中的属性#
假设我有这门课C# 为什么列表的副本仍然使用C更改原始列表中的属性#,c#,.net,properties,deep-copy,shallow-copy,C#,.net,Properties,Deep Copy,Shallow Copy,假设我有这门课 public class Employee { public string FirstName { get; set; } public string LastName { get; set; } public bool isActive { get; set; } } 然后像这样使用它: List<Employee> Employees = new List<Employee>(); Employees.Add(
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool isActive { get; set; }
}
然后像这样使用它:
List<Employee> Employees = new List<Employee>();
Employees.Add(new Employee { FirstName = "firstname", LastName = "lastname", isActive = true });
List<Employee> EmployeesCopy = new List<Employee>(Employees);
EmployeesCopy[0].isActive = false;
List<Employee> Employees = new List<Employee>();
Employees.Add(new Employee { FirstName = "firstname", LastName = "lastname", isActive = true });
List<Employee> EmployeesCopy = Employees.Select(x => new Employee(x)).ToList();
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool isActive { get; set; }
public Employee()
{ }
public Employee(Employee e)
{
FirstName = e.FirstName;
LastName = e.LastName;
isActive = e.isActive;
}
}
List Employees=newlist();
添加(新员工{FirstName=“FirstName”,LastName=“LastName”,isActive=true});
列表员工透视=新列表(员工);
员工透视[0]。isActive=false;
为什么
EmployeeScope
的isActive
属性的更改也会修改原始列表中的属性 副本是一个新的列表
对象,但它包含对原始列表中同一组员工
对象的引用。如果希望两个列表中的Employee
对象是独立的,则必须分别复制它们并将副本放入新列表中 你在做浅拷贝,而不是深拷贝。这意味着新列表包含与原始列表相同的对象
要进行深度复制,您需要遍历原始列表,并为新列表创建新的Employee
对象,如下所示
private List<Employee> CloneEmployees(List<Employee> original)
{
var newList = new List<Employee>();
foreach (var employee in original)
{
newList.Add(new Employee
{
FirstName = employee.FirstName,
LastName = employee.LastName,
isActive = employee.isActive
});
}
return newList;
}
CloneEmployees私人列表(列表原件)
{
var newList=新列表();
foreach(var员工原件)
{
newList.Add(新员工)
{
FirstName=employee.FirstName,
LastName=employee.LastName,
isActive=employee.isActive
});
}
返回newList;
}
您创建的副本只是列表的副本。不是对象的副本。换句话说,employeescope[0]==employeescope[0]
因为使用新列表(员工)代码>将为您提供列表的新实例,但不提供列表中包含的对象。还应该考虑对列表中包含的对象进行克隆,使用二进制序列化来序列化对象图。
为什么员工的isActive属性的变化也会改变
原始列表|
因为这两个列表都指向Employee对象的同一个实例。您还需要创建您的Employee对象 因为新列表仍然包含对相同employee对象的引用。您可以通过以下操作在新列表中创建新列表:
List<Employee> Employees = new List<Employee>();
Employees.Add(new Employee { FirstName = "firstname", LastName = "lastname", isActive = true });
List<Employee> EmployeesCopy = new List<Employee>(Employees);
EmployeesCopy[0].isActive = false;
List<Employee> Employees = new List<Employee>();
Employees.Add(new Employee { FirstName = "firstname", LastName = "lastname", isActive = true });
List<Employee> EmployeesCopy = Employees.Select(x => new Employee(x)).ToList();
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool isActive { get; set; }
public Employee()
{ }
public Employee(Employee e)
{
FirstName = e.FirstName;
LastName = e.LastName;
isActive = e.isActive;
}
}
List Employees=newlist();
添加(新员工{FirstName=“FirstName”,LastName=“LastName”,isActive=true});
列出EmployeesCopy=Employees.Select(x=>newemployeex)).ToList();
公营雇员
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共bool isActive{get;set;}
公职人员()
{ }
公共雇员(雇员e)
{
FirstName=e.FirstName;
LastName=e.LastName;
isActive=e.isActive;
}
}
因为员工
是一种参考类型(类)。是时候回到书本上了,这样你才能清楚地理解参考类型和价值类型之间的区别了。这件事真的很重要。确保你得到它。这可能会帮助你是的,它不是和员工副本,但只是另一个包含相同员工的列表。这是一个问得很好(但重复)的问题。它不值得投否决票+1如果实现Employee
会更好。嗯,我认为在这个级别上,复制构造函数就可以了。