FrankTominc February 2016

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

Answers


Wai Ha Lee February 2016

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.


Yacoub Massad February 2016

With LINQ, you can do something like this:

public List<List<T>> Clone<T>(List<List<T>> original) where T : ICloneable
{
    return original
        .Select(sl => sl.Select(x => (T)x.Clone()).ToList())
        .ToList();
}

Post Status

Asked in February 2016
Viewed 3,788 times
Voted 14
Answered 2 times

Search




Leave an answer