Demin K
Demin K

Reputation: 11

Update in one list is changing the other even if deep copy c#

I have following code having two lists studentList and clonedStudentList of Student class in which one is a deep copy of other. I am updating one list but other list should not be changed. But still it is changing. In the code I am just checking if any student have StudentId2 from studentList update the StudentId value of clonedStudentList by getting the new value from studentid2 ref dictionary.And if student dont have studentId2 value update the StudentId value of clonedStudentList by getting the new value from studentid ref dictionary

var clonedStudentList = studentList.ToList();
clonedStudentList.ForEach(x =>
{
   studentList.ForEach(y =>
   {
     if (y.StudentId2.HasValue && StudentIds2Dictionary.ContainsKey(y.StudentId2.Value))
     {
       x.StudentId= StudentIds2Dictionary[y.StudentId2.Value];
     }
     else if(StudentIdsDictionary.ContainsKey(y.StudentId.Value))
     {
       x.StudentId= StudentIdsDictionary[y.StudentId.Value];
     }
   });
});

I have also used

var clonedStudentList = new List<Student>(studentList);

but still the same issue.

Any help?

Upvotes: 0

Views: 158

Answers (1)

Patrick Artner
Patrick Artner

Reputation: 51643

Use this to check your facts: The static ObjectIDGenerator gives u a unique ID for each thing it knows about. You are not deep copying by clonedStudentList = new List<Student>(studentList); elsewise the IDs would not match afterwards:

You are simply creating a new List that contains the same references to Student objects as the one before. Write your own Copy-Method that creates new Students by copying the internals over.

internal class Program
{
    static void Main(string[] args)
    {
        string[] data = "One;Two;Dhree;Four;Vive;Six;Ceven;Eight;Nine;Pen".Split(';');

        var studs = data.Select(d => new Student(d, d.Length < 4 ? "m" : "f")).ToList();

        var l2 = new List<Student>(studs);

        var l3 = studs.Select(s => Student.CopyMe(s));

        Console.WriteLine("Org:");
        Console.WriteLine("    " + string.Join("\n    ", studs));

        Console.WriteLine("'deep':");
        Console.WriteLine("    " + string.Join("\n    ", l2));

        Console.WriteLine("'copied':");
        Console.WriteLine("    " + string.Join("\n    ", l3));

        Console.ReadLine();
    }
}

internal class Student
{
    public Student(string name, string gender)
    {
        Name = name;
        Gender = gender;
    }

    public string Gender { get; set; }
    public string Name { get; set; }

    public static Student CopyMe(Student s)
    {
        return new Student(s.Name, s.Gender);
    }

    public override string ToString()
    {
        return string.Join(" ", new[] { Name, Gender, g.GetId(this, out var firstTime).ToString() });
    }

    private static ObjectIDGenerator g = new ObjectIDGenerator();
}

Output:

Org:
    One m 1
    Two m 2
    Dhree f 3
    Four f 4
    Vive f 5
    Six m 6
    Ceven f 7
    Eight f 8
    Nine f 9
    Pen m 10

'deep':  // SAME IDs as before
    One m 1
    Two m 2
    Dhree f 3
    Four f 4
    Vive f 5
    Six m 6
    Ceven f 7
    Eight f 8
    Nine f 9
    Pen m 10

'copied': // NEW ids
    One m 11
    Two m 12
    Dhree f 13
    Four f 14
    Vive f 15
    Six m 16
    Ceven f 17
    Eight f 18
    Nine f 19
    Pen m 20

I added // comments to the output after the fact.

Upvotes: 1

Related Questions