without How do I clone a generic list in C#?




copy data from one list to another c# linq (19)

I have a generic list of objects in C#, and wish to clone the list. The items within the list are cloneable, but there doesn't seem to be an option to do list.Clone().

Is there an easy way around this?


public static Object CloneType(Object objtype)
{
    Object lstfinal = new Object();

    using (MemoryStream memStream = new MemoryStream())
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
        binaryFormatter.Serialize(memStream, objtype); memStream.Seek(0, SeekOrigin.Begin);
        lstfinal = binaryFormatter.Deserialize(memStream);
    }

    return lstfinal;
}

    public List<TEntity> Clone<TEntity>(List<TEntity> o1List) where TEntity : class , new()
    {
        List<TEntity> retList = new List<TEntity>();
        try
        {
            Type sourceType = typeof(TEntity);
            foreach(var o1 in o1List)
            {
                TEntity o2 = new TEntity();
                foreach (PropertyInfo propInfo in (sourceType.GetProperties()))
                {
                    var val = propInfo.GetValue(o1, null);
                    propInfo.SetValue(o2, val);
                }
                retList.Add(o2);
            }
            return retList;
        }
        catch
        {
            return retList;
        }
    }

Another thing: you could use reflection. If you'll cache this properly, then it'll clone 1,000,000 objects in 5.6 seconds (sadly, 16.4 seconds with inner objects).

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Person
{
       ...
      Job JobDescription
       ...
}

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Job
{...
}

private static readonly Type stringType = typeof (string);

public static class CopyFactory
{
    static readonly Dictionary<Type, PropertyInfo[]> ProperyList = new Dictionary<Type, PropertyInfo[]>();

    private static readonly MethodInfo CreateCopyReflectionMethod;

    static CopyFactory()
    {
        CreateCopyReflectionMethod = typeof(CopyFactory).GetMethod("CreateCopyReflection", BindingFlags.Static | BindingFlags.Public);
    }

    public static T CreateCopyReflection<T>(T source) where T : new()
    {
        var copyInstance = new T();
        var sourceType = typeof(T);

        PropertyInfo[] propList;
        if (ProperyList.ContainsKey(sourceType))
            propList = ProperyList[sourceType];
        else
        {
            propList = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            ProperyList.Add(sourceType, propList);
        }

        foreach (var prop in propList)
        {
            var value = prop.GetValue(source, null);
            prop.SetValue(copyInstance,
                value != null && prop.PropertyType.IsClass && prop.PropertyType != stringType ? CreateCopyReflectionMethod.MakeGenericMethod(prop.PropertyType).Invoke(null, new object[] { value }) : value, null);
        }

        return copyInstance;
    }

I measured it in a simple way, by using the Watcher class.

 var person = new Person
 {
     ...
 };

 for (var i = 0; i < 1000000; i++)
 {
    personList.Add(person);
 }
 var watcher = new Stopwatch();
 watcher.Start();
 var copylist = personList.Select(CopyFactory.CreateCopyReflection).ToList();
 watcher.Stop();
 var elapsed = watcher.Elapsed;

RESULT: With inner object PersonInstance - 16.4, PersonInstance = null - 5.6

CopyFactory is just my test class where I have dozen of tests including usage of expression. You could implement this in another form in an extension or whatever. Don't forget about caching.

I didn't test serializing yet, but I doubt in an improvement with a million classes. I'll try something fast protobuf/newton.

P.S.: for the sake of reading simplicity, I only used auto-property here. I could update with FieldInfo, or you should easily implement this by your own.

I recently tested the Protocol Buffers serializer with the DeepClone function out of the box. It wins with 4.2 seconds on a million simple objects, but when it comes to inner objects, it wins with the result 7.4 seconds.

Serializer.DeepClone(personList);

SUMMARY: If you don't have access to the classes, then this will help. Otherwise it depends on the count of the objects. I think you could use reflection up to 10,000 objects (maybe a bit less), but for more than this the Protocol Buffers serializer will perform better.


public class CloneableList<T> : List<T>, ICloneable where T : ICloneable
{
  public object Clone()
  {
    var clone = new List<T>();
    ForEach(item => clone.Add((T)item.Clone()));
    return clone;
  }
}

There is a simple way to clone objects in C# using a JSON serializer and deserializer.

You can create an extension class:

using Newtonsoft.Json;

static class typeExtensions
{
    [Extension()]
    public static T jsonCloneObject<T>(T source)
    {
    string json = JsonConvert.SerializeObject(source);
    return JsonConvert.DeserializeObject<T>(json);
    }
}

To clone and object:

obj clonedObj = originalObj.jsonCloneObject;

If your elements are value types, then you can just do:

List<YourType> newList = new List<YourType>(oldList);

However, if they are reference types and you want a deep copy (assuming your elements properly implement ICloneable), you could do something like this:

List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);

oldList.ForEach((item) =>
    {
        newList.Add((ICloneable)item.Clone());
    });

Obviously, replace ICloneable in the above generics and cast with whatever your element type is that implements ICloneable.

If your element type doesn't support ICloneable but does have a copy-constructor, you could do this instead:

List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);

oldList.ForEach((item)=>
    {
        newList.Add(new YourType(item));
    });

Personally, I would avoid ICloneable because of the need to guarantee a deep copy of all members. Instead, I'd suggest the copy-constructor or a factory method like YourType.CopyFrom(YourType itemToCopy) that returns a new instance of YourType.

Any of these options could be wrapped by a method (extension or otherwise).


You could also simply convert the list to an array using ToArray, and then clone the array using Array.Clone(...). Depending on your needs, the methods included in the Array class could meet your needs.


For a shallow copy, you can instead use the GetRange method of the generic List class.

List<int> oldList = new List<int>( );
// Populate oldList...

List<int> newList = oldList.GetRange(0, oldList.Count);

Quoted from: Generics Recipes


If you have already referenced Newtonsoft.Json in your project and your objects are serializeable you could always use:

List<T> newList = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(listToCopy))

Possibly not the most efficient way to do it, but unless you're doing it 100s of 1000s of times you may not even notice the speed difference.


Unless you need an actual clone of every single object inside your List<T>, the best way to clone a list is to create a new list with the old list as the collection parameter.

List<T> myList = ...;
List<T> cloneOfMyList = new List<T>(myList);

Changes to myList such as insert or remove will not affect cloneOfMyList and vice versa.

The actual objects the two Lists contain are still the same however.


public static object DeepClone(object obj) 
{
  object objResult = null;
  using (MemoryStream  ms = new MemoryStream())
  {
    BinaryFormatter  bf =   new BinaryFormatter();
    bf.Serialize(ms, obj);

    ms.Position = 0;
    objResult = bf.Deserialize(ms);
  }
  return objResult;
}

This is one way to do it with C# and .NET 2.0. Your object requires to be [Serializable()]. The goal is to lose all references and build new ones.


 //try this
 List<string> ListCopy= new List<string>(OldList);
 //or try
 List<T> ListCopy=OldList.ToList();

I've made for my own some extension which converts ICollection of items that not implement IClonable

static class CollectionExtensions
{
    public static ICollection<T> Clone<T>(this ICollection<T> listToClone)
    {
        var array = new T[listToClone.Count];
        listToClone.CopyTo(array,0);
        return array.ToList();
    }
}

If you need a cloned list with the same capacity, you can try this:

public static List<T> Clone<T>(this List<T> oldList)
{
    var newList = new List<T>(oldList.Capacity);
    newList.AddRange(oldList);
    return newList;
}

I use automapper to copy an object. I just setup a mapping that maps one object to itself. You can wrap this operation any way you like.

http://automapper.codeplex.com/


Use AutoMapper (or whatever mapping lib you prefer) to clone is simple and a lot maintainable.

Define your mapping:

Mapper.CreateMap<YourType, YourType>();

Do the magic:

YourTypeList.ConvertAll(Mapper.Map<YourType, YourType>);

You can use extension method:

namespace extension
{
    public class ext
    {
        public static List<double> clone(this List<double> t)
        {
            List<double> kop = new List<double>();
            int x;
            for (x = 0; x < t.Count; x++)
            {
                kop.Add(t[x]);
            }
            return kop;
        }
   };

}

You can clone all objects by using their value type members for example, consider this class:

public class matrix
{
    public List<List<double>> mat;
    public int rows,cols;
    public matrix clone()
    { 
        // create new object
        matrix copy = new matrix();
        // firstly I can directly copy rows and cols because they are value types
        copy.rows = this.rows;  
        copy.cols = this.cols;
        // but now I can no t directly copy mat because it is not value type so
        int x;
        // I assume I have clone method for List<double>
        for(x=0;x<this.mat.count;x++)
        {
            copy.mat.Add(this.mat[x].clone());
        }
        // then mat is cloned
        return copy; // and copy of original is returned 
    }
};

Note: if you do any change on copy (or clone) it will not affect the original object.


The following code should transfer onto a list with minimal changes.

Basically it works by inserting a new random number from a greater range with each successive loop. If there exist numbers already that are the same or higher than it, shift those random numbers up one so they transfer into the new larger range of random indexes.

// Example Usage
int[] indexes = getRandomUniqueIndexArray(selectFrom.Length, toSet.Length);

for(int i = 0; i < toSet.Length; i++)
    toSet[i] = selectFrom[indexes[i]];


private int[] getRandomUniqueIndexArray(int length, int count)
{
    if(count > length || count < 1 || length < 1)
        return new int[0];

    int[] toReturn = new int[count];
    if(count == length)
    {
        for(int i = 0; i < toReturn.Length; i++) toReturn[i] = i;
        return toReturn;
    }

    Random r = new Random();
    int startPos = count - 1;
    for(int i = startPos; i >= 0; i--)
    {
        int index = r.Next(length - i);
        for(int j = startPos; j > i; j--)
            if(toReturn[j] >= index)
                toReturn[j]++;
        toReturn[i] = index;
    }

    return toReturn;
}

After a slight modification you can also clone:

public static T DeepClone<T>(T obj)
{
    T objResult;
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, obj);
        ms.Position = 0;
        objResult = (T)bf.Deserialize(ms);
    }
    return objResult;
}




clone