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?
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?
Don't think there is a built in way to do this. I would make an extension on List.
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 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).
If you know the type:
List<int> newList = new List<int>(oldList);
If you don't know the type before, you'll need a helper function:
List<T> Clone<T>(IEnumerable<T> oldList)
{
return newList = new List<T>(oldList);
}
The just:
List<string> myNewList = Close(myOldList);
You can use an extension method.
static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}
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 framework 2.0. Your object require to be [Serializable()]... This method Serialize and unserialize. The goal is to lost all reference and build new one.