2

I need to clone lists in different parts of the system I'm working on and I came up with the below solution, but I'm still concerned about it's performance I've been wondering if that is a good method at all. So I decided to post it here so that I can find if there is any problem or flaw related to this method of cloning objects. And if it is a bad move, I'd like to know what is the best approach.

My extension method for cloning a list:

    public static List<T> Clone<T>(this List<T> input)
    {
        using (System.IO.MemoryStream Mems = new System.IO.MemoryStream())
        {
            XmlSerializer Serializer = new XmlSerializer(typeof(T));
            Serializer.Serialize(Mems, input);
            var Deserialized = Serializer.Deserialize(Mems) as List<T>;
            return Deserialized;
        }
    }

Update: Assuming T is a value type (Always)

Arnold Zahrneinder
  • 4,788
  • 10
  • 40
  • 76
  • 1
    Look at this : http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c – Shashank Shekhar Mar 27 '15 at 21:20
  • @Shekhar: If the T is a value time, then does that change the memory location of the original value in the second list. I think the memory location remains the same meaning the list is not cloned but copied. – Arnold Zahrneinder Mar 27 '15 at 21:22
  • @Shekhar: I'm speaking about VALUE type not a reference type that implement IClonable – Arnold Zahrneinder Mar 27 '15 at 21:24
  • I think it is at least not bad practice, so this method should work fine. Are you using xml serialization just because to support objects without `Serializable` attribute? – nikis Mar 27 '15 at 21:25
  • you should update that in the question – Shashank Shekhar Mar 27 '15 at 21:25
  • @nikis: Yeah the T is always (in this case) a value type, so there is no Serailizable attribute in this case. – Arnold Zahrneinder Mar 27 '15 at 21:26
  • 1
    Value types are always copied, so you don't have to worry about deep cloning (it's always new). For reference types it's a little trickier, since `ICloneable` does not guarantee a deep clone ([MSDN](https://msdn.microsoft.com/en-us/library/system.icloneable%28v=vs.110%29.aspx)). Your serialization method is probably the easiest way to deal with reference types. – Setsu Mar 27 '15 at 21:26

1 Answers1

-1

That adds a considerable performance hit and wastes memory (XML is verbose).

Shallow clone:

public static List<T> Clone<T>(this List<T> input)
{
    return new List<T>(input);
}

Deep clone:

public static List<T> Clone<T>(this List<T> input) where T : ICloneable
{
    var cloned = new List<T>(input.Capacity);
    cloned.AddRange(input.Select(item => (T) item.Clone()));
    return cloned;
}
Zer0
  • 7,191
  • 1
  • 20
  • 34
  • 1
    This is shallow cloning. – usr Mar 27 '15 at 21:22
  • refer to my comment under my post – Arnold Zahrneinder Mar 27 '15 at 21:22
  • @usr - No need for downvote. He specified value types so that's completely irrelevant. But I added a deep clone anyways. – Zer0 Mar 27 '15 at 21:28
  • Your deep clone is flawed, because `ICloneable` doesn't guarantee a deep clone ([MSDN](https://msdn.microsoft.com/en-us/library/system.icloneable%28v=vs.110%29.aspx)). – Setsu Mar 27 '15 at 21:28
  • Value types can have reference members which would be skipped by this procedure. – usr Mar 27 '15 at 21:29
  • 1
    @Setsu - No, it doesn't. But if he's closing his own types he would implement a deep copy. – Zer0 Mar 27 '15 at 21:30
  • Does this deep cloning method really have a higher performance comparing to my serialization method? Saying this because the LINQ is already slow unless you do PLINQ, and each object must have its own cloning function, THAT cloning function is important, so all these things together make it pretty slow as well! – Arnold Zahrneinder Mar 27 '15 at 21:40
  • 1
    @Arrr - Yes, this should be far faster if implemented correctly. I could benchmark for you if I had a type. – Zer0 Mar 27 '15 at 21:42
  • @Zer0: Well I recommend you to make it parallel before the select, it would considerably add up performance. Higher CPU usage, faster cloning – Arnold Zahrneinder Mar 27 '15 at 21:44
  • @Arrrr - That would only make sense if the clone is very expensive. There's overhead to doing things in parallel. My guess is PLINQ likely wouldn't even do this in parallel in most cases. But back to the point - this will be much, much faster than XML serialization and use less memory. – Zer0 Mar 27 '15 at 21:51
  • @Zer0: It does do it in parallel, though using Parallel Foreach is also possible to maximize the performance – Arnold Zahrneinder Mar 27 '15 at 22:24