1

I have a class which contains local and global employees. Both the employees have same list data. When I change the name of one list employee, other list employee name also gets changed.

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;
    }
}

Test Class

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

Employee Data

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

Assignment Part

    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);

Now, both the employee names as shown above are changed to Mike. Please help me resolve the issue. Thanks!

Pearl
  • 8,373
  • 8
  • 40
  • 59
  • The reason for change in one `List` also update value in `another list` is you are having `List of Class`. And `Class` is `reference` type. So what happen in `List` is both `List` are `referencing` to `same memory`. Thus when you update any of the `object` it will reflect on both. – Karan Aug 11 '20 at 08:17
  • Karan, yes, that's true. is there any thing we can do to resolve the issue? – Pearl Aug 11 '20 at 08:28
  • Please check these [my answer](https://stackoverflow.com/a/63354232/9695286) or [answer from Sowmyadhar Gourishetty](https://stackoverflow.com/a/63354181/9695286) – Karan Aug 11 '20 at 08:44

3 Answers3

3

List of the object in c# are always reference types. In your case you are adding the same reference to localEmployees and globalEmployees and that's the reason changing in one list is updating the other

Refer more about Reference type here

Solution 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", "FOOTBALL", 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", "Parvez Ali", "FOOTBALL", 1));
    gemployees.Add(new Employee("AALI_e2", "Ashik Ali", "FOOTBALL", 1));
    gemployees.Add(new Employee("AALI_e3", "Aftab Ali", "CHESS", 2));
    gemployees.Add(new Employee("AALI_e4", "Arif Ali", "CRICKET", 3));

Assign them:

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

Solution 2:

Using the IClonable Interface and create a copy of the object and assign it to the other variable/property, Please refer more here

Sowmyadhar Gourishetty
  • 1,843
  • 1
  • 8
  • 15
1

The reason for change in one List also update value in another list is you are having List of Class. And Class is reference type. So what happen in List is both List are referencing to same memory. Thus when you update any of the object it will reflect on both.

You can use linq Select to instantiate new objects like below.

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.Name, e.eventHeld, e.eventId)).ToList();
Karan
  • 12,059
  • 3
  • 24
  • 40
1

This is how to solve your problem:

class Program
{
    static void Main()
    {
        var employees = new List<Employee>();
        employees.Add(new Employee("PALI_e1", "Parvez Ali", "FOOTBALL", 1));
        employees.Add(new Employee("AALI_e2", "Ashik Ali", "FOOTBALL", 1));
        employees.Add(new Employee("AALI_e3", "Aftab Ali", "CHESS", 2));
        employees.Add(new Employee("AALI_e4", "Arif Ali", "CRICKET", 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);
    }
}

Output:

Mike

Ashik Ali

You were experiencing this issue, cause both the lists were referencing the same memory references.

The .Select(x => x.Clone()).ToList() will create a new copy over every value in the list, solving the problem.

Marco Salerno
  • 5,131
  • 2
  • 12
  • 32