Search code examples
c#.netdeep-copyicloneable

Proper way to Clone a List<List<T>> in C#


I'm struggling to clone a list of lists of a reference type. I tried to implement ICloneable in my reference class, however, it don't seems to call the Clone() method in it.

Code:

public class Solid : ICloneable{

    private double[,] _points;  //vertices do solido
    private int[,] _edges;  //arestas do solido
    public int[,] Faces { get; private set; }   //faces do solido

    public int[,] Edges {
        get { return _edges; }
        set { _edges = value; }

    }
    ...

    public object Clone() {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();

        bf.Serialize(ms, this);

        ms.Position = 0;
        object obj = bf.Deserialize(ms);
        ms.Close();
        return obj;
    }
}

Solution

  • You have a List<List<T>>, where T is ICloneable.

    Obviously for each T you just call Clone() to get an object (which you can turn into a T by casting back), but to get a clone of the nested list you need something like:

    public static List<List<T>> Clone<T>(List<List<T>> original)
        where T : ICloneable
    {
        var result = new List<List<T>>();
        foreach ( List<T> innerList in original )
        {
            var innerResult = new List<T>();
            foreach ( T item in innerList )
            {
                var clone = (T)item.Clone();
                innerResult.Add(clone);
            }
    
            result.Add(innerResult);
        }
    
        return result;
    }
    

    This will ensure that Clone() is called on each T, and the lists (outer and nested) are separate instances to the original.