更改一个列表项会更改其他列表项

问题描述

我有一个包含本地和全球员工的课程。两名员工都有相同的列表数据。当我更改一个列表员工的姓名时,其他列表员工的姓名也会更改。

public class Employee
{
    public string employeeID;
    public string Name;
    public string eventHeld;
    public int eventId;

    public Employee(string eID,string eName,string eEvents,int eId)
    {
        this.employeeID = eID;
        this.Name = eName;
        this.eventHeld = eEvents;
        this.eventId = eId;
    }
}

测试类

public class TestClass
{
    public List<Employee> localEmployees = new List<Employee>();
    public List<Employee> globalEmployees = new List<Employee>();
}

员工数据

    List<Employee> employees = new List<Employee>();
    employees.Add(new Employee("PALI_e1","Parvez Ali","FOOTBALL",1));
    employees.Add(new Employee("AALI_e2","Ashik Ali",1));
    employees.Add(new Employee("AALI_e3","Aftab Ali","CHESS",2));
    employees.Add(new Employee("AALI_e4","Arif Ali","CRICKET",3));

分配部分

    TestClass obj = new TestClass();
    obj.localEmployees = employees;
    obj.globalEmployees = employees;

    obj.globalEmployees[0].Name = "Mike";
    Console.WriteLine(obj.globalEmployees[0].Name);
    Console.WriteLine(obj.localEmployees[0].Name);

现在,上面显示的两个雇员姓名都更改为Mike。请帮助我解决问题。谢谢!

解决方法

在更新时,c#中的对象列表始终是引用类型。在您的情况下,您要向localEmployees和globalEmployees添加相同的引用,这就是在一个列表中进行更改会更新另一个列表的原因

有关参考类型here

的更多信息

解决方案1:

 List<Employee> lemployees = new List<Employee>();
    List<Employee> gemployees = new List<Employee>();
    lemployees.Add(new Employee("PALI_e1","Parvez Ali","FOOTBALL",1));
    lemployees.Add(new Employee("AALI_e2","Ashik Ali",1));
    lemployees.Add(new Employee("AALI_e3","Aftab Ali","CHESS",2));
    lemployees.Add(new Employee("AALI_e4","Arif Ali","CRICKET",3));

    gemployees.Add(new Employee("PALI_e1",1));
    gemployees.Add(new Employee("AALI_e2",1));
    gemployees.Add(new Employee("AALI_e3",2));
    gemployees.Add(new Employee("AALI_e4",3));

分配他们:

TestClass obj = new TestClass();
obj.localEmployees = lemployees;
obj.globalEmployees = gemployees;

解决方案2:

使用IClonable接口并创建对象的副本,并将其分配给其他变量/属性,请参阅更多here

,

更改一个List也会更新another list中的值的原因是您拥有List of ClassClassreference类型。因此,在List中发生的事情是两个List都是referencingsame memory。因此,当您更新任何object时,它将同时反映在两者上。

您可以使用linq Select实例化如下所示的新对象。

obj.localEmployees = employees.Select(e => new Employee(e.employeeID,e.Name,e.eventHeld,e.eventId)).ToList();
obj.globalEmployees = employees.Select(e => new Employee(e.employeeID,e.eventId)).ToList();
,

这是解决问题的方法:

class Program
{
    static void Main()
    {
        var employees = new List<Employee>();
        employees.Add(new Employee("PALI_e1",1));
        employees.Add(new Employee("AALI_e2",1));
        employees.Add(new Employee("AALI_e3",2));
        employees.Add(new Employee("AALI_e4",3));

        var globalEmployees = employees.Select(x => x.Clone()).ToList();

        employees[0].Name = "Mike";

        Console.WriteLine(employees[0].Name);
        Console.WriteLine(employees[1].Name);
    }
}

public class Employee
{
    public string EmployeeID { get; set; }
    public string Name { get; set; }
    public string EventHeld { get; set; }
    public int EventId { get; set; }

    public Employee(string employeeID,string name,string eventHeld,int eventId)
    {
        this.EmployeeID = employeeID;
        this.Name = name;
        this.EventHeld = eventHeld;
        this.EventId = eventId;
    }

    public Employee Clone()
    {
        return new Employee(EmployeeID,Name,EventHeld,EventId);
    }
}

输出:

迈克

Ashik Ali

您遇到了此问题,因为两个列表都引用了相同的内存引用。

.Select(x => x.Clone()).ToList()将在列表中的每个值上创建一个新副本,以解决问题。