2013-03-14 1 views
2

Допустим, у меня есть этот классПочему копия списка до сих пор изменения свойств в исходном списке, используя C#

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; 

Почему изменения в isActive собственности от EmployeesCopy также изменить собственность в первоначальном списке?

+3

Потому что 'Employee' является ссылочным типом (классом). –

+0

Время, чтобы вернуться к книгам, чтобы вы четко понимали разницу между ссылочными и стоимостными типами. Этот sh * t очень важен. Убедитесь, что вы его получили. – spender

+0

может быть, это поможет вам http://www.codeproject.com/Articles/76153/Six-important-NET-concepts-Stack-heap-value-types – 1Mayur

ответ

3

Поскольку новый список все еще содержит ссылки на одни и те же объекты работника. Вы можете создать новые в новом списке, выполнив что-то вроде этого:

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

Было бы лучше, если бы «Сотрудник» реализовал ['IClonable'] (http://msdn.microsoft.com/en-us/library/system.icloneable.aspx). – Leri

+0

ICloneable .... – spender

+2

Ну, я думаю, что на этом уровне конструктор копирования будет в порядке. – laszlokiss88

0

Копия представляет собой новый объект List, но содержит ссылки на тот же набор Employee объектов, которые находятся в первоначальном списке. Если вы хотите, чтобы объекты Employee в двух списках были независимыми, вы должны их скопировать отдельно и поместить копии в новый список.

1

Вы делаете мелкую копию, а не глубокую копию. Это означает, что новый список содержит те же объекты из исходного списка.

Чтобы сделать глубокую копию, вам нужно будет перебирать исходный список и создавать новые 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; 
} 
0

Созданная вами копия является просто копией списка. Не копия объектов. Другими словами, Employees[0] == EmployeesCopy[0].

0

, поскольку с помощью new List<Employee>(Employees); вы получите новый экземпляр списка, но не объекты, содержащиеся в списке. Вы также должны рассмотреть клонирование объектов, содержащихся в списке, с помощью Binary Serialization для сериализации графа объектов.

1

Почему изменение свойства isActive EmployeesCopy также вносит изменения в исходный список? |

Поскольку оба списка указывают на один и тот же экземпляр объекта Employee. Вам также необходимо указать deep copy свой объект Employee.