none
Copy List<SomeObject> to Clone List RRS feed

  • Question

  • Hello!

    How to copy List of some objects (not by reference, by value) to another list the same of type.

    TIA
    • Edited by DioNNiS Tuesday, August 26, 2008 1:56 PM 1234
    Tuesday, August 26, 2008 1:55 PM

Answers

  • If you want to copy the entire list to a new list, you could do something like the following:

    List<Widget> newWidgetList = new List<Widget>(oldWidgetList);

    However, the objects within the list will still be the same reference for each.

    The only way to clone the objects in the lists is to implement a .Clone() method that clones the objects themselves.  This can either be a shallow clone, or one of the more popular ways to accomplish this is to make your objects serializable, and then serialize and deserialize the current object, returning the deserialized version.  Then you'd have to clone each individual item.

    Of course, you could clone the entire list at once, assuming all your objects are marked with the [Serializable] attribute.

    public static List<T> CloneList<T>(List<T> oldList)  
    {  
        BinaryFormatter formatter = new BinaryFormatter();  
        MemoryStream stream = new MemoryStream();  
        formatter.Serialize(stream, oldList);  
        stream.Position = 0;  
        return (List<T>)formatter.Deserialize(stream);      

    David Morton - http://blog.davemorton.net/
    • Marked as answer by DioNNiS Wednesday, August 27, 2008 8:27 AM
    Tuesday, August 26, 2008 2:18 PM
    Moderator

All replies

  • If you want to copy the entire list to a new list, you could do something like the following:

    List<Widget> newWidgetList = new List<Widget>(oldWidgetList);

    However, the objects within the list will still be the same reference for each.

    The only way to clone the objects in the lists is to implement a .Clone() method that clones the objects themselves.  This can either be a shallow clone, or one of the more popular ways to accomplish this is to make your objects serializable, and then serialize and deserialize the current object, returning the deserialized version.  Then you'd have to clone each individual item.

    Of course, you could clone the entire list at once, assuming all your objects are marked with the [Serializable] attribute.

    public static List<T> CloneList<T>(List<T> oldList)  
    {  
        BinaryFormatter formatter = new BinaryFormatter();  
        MemoryStream stream = new MemoryStream();  
        formatter.Serialize(stream, oldList);  
        stream.Position = 0;  
        return (List<T>)formatter.Deserialize(stream);      

    David Morton - http://blog.davemorton.net/
    • Marked as answer by DioNNiS Wednesday, August 27, 2008 8:27 AM
    Tuesday, August 26, 2008 2:18 PM
    Moderator
  • Sounds like what you want is to deep copy objects in a collection.  First, you need to know how to deep copy each object.  Some types are easy, like value types and simple reference types (like String, can essentially be deep copied with newValue = new String(oldValue);).

    One common patterns is to implement a clone method on the class you want to deep copy, usually something intention-revealing like DeepClone.  If you have that then it's easy to copy "by value" one list to another.  For example:
            public static List<MyClass> CopyList(List<MyClass> list)  
            {  
                List<MyClass> newList = new List<MyClass>(list.Count);  
                foreach (MyClass item in list)  
                    newList.Add(item.DeepClone());  
                return newList;  
            }  
     

    http://www.peterRitchie.com/blog
    Tuesday, August 26, 2008 2:21 PM
    Moderator
  • Please, any sample of DeepClone ?? thanks.

     

    I have this, which is better way for clone ??

     

     

    public static List<T> CloneList<T>(List<T> oldList)

    {

     

    BinaryFormatter formatter = new BinaryFormatter();

     

    MemoryStream stream = new MemoryStream();

    formatter.Serialize(stream, oldList);

    stream.Position = 0;

     

    return (List<T>)formatter.Deserialize(stream);

    }

     

     

    public static List<T> CopyList<T>(List<T> list) where T : ICloneable

    {

     

    var newList = new List<T>(list.Count);

     

    foreach (T item in list)

    newList.Add((T)item.Clone());

     

    return newList;

    }

     

    Friday, June 25, 2010 8:46 AM
  • Some time ago, I wrote this piece of code for demonstration purpose only. I don't use it and it's far from being fully debugged. See if it fits your needs.

        public static void DeepCopy<T>(this T destination, T source)
        {
          DeepCopy(destination, source, new List<object>());
        }
        static void DeepCopy<T>(this T destination, T source, List<object> visited)
        {
          if (visited.Contains(source))
            return;
          visited.Add(source);
          Type t = destination.GetType();
          if (!t.IsAssignableFrom(source.GetType()))
            t = source.GetType();
          foreach (FieldInfo field in t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
          {
            object value = field.GetValue(source);
            ConstructorInfo ctor = null;
            if (value != null && value.GetType().IsClass)
              ctor = value.GetType().GetConstructor(Type.EmptyTypes);
            if (ctor != null)
            {
              object newvalue = ctor.Invoke(null);
              DeepCopy(newvalue, value, visited);
            }
            else
              field.SetValue(destination, field.GetValue(source));
          }
        }
    Friday, June 25, 2010 8:59 AM