Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么列表的副本仍然使用C更改原始列表中的属性#_C#_.net_Properties_Deep Copy_Shallow Copy - Fatal编程技术网

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
会更好。嗯,我认为在这个级别上,复制构造函数就可以了。