Clone lists and arrays of objects in C#

[clone]

This is the last post I’ll write about clones, at least for a while. Some collection classes can already make clones. For example, an array can clone itself, although the result is always a shallow clone. This example shows how to add extension methods that allow arrays and lists to make both shallow and deep clones.

The following code shows the new extension methods. (These are simplified versions based on the comment below by E. Anderson.)

// Return a deep clone of a list.
public static List<T> DeepClone<T>(this List<T> items)
{
    var query = from T item in items select item.DeepClone();
    return new List<T>(query);
}

// Return a deep clone of an array.
public static T[] DeepClone<T>(this T[] items)
{
    var query = from T item in items select item.DeepClone();
    return query.ToArray();
}

// Return a shallow clone of a list.
public static List<T> ShallowClone<T>(this List<T> items)
{
    return new List<T>(items);
}

// Return a shallow clone of an array.
public static T[] ShallowClone<T>(this T[] items)
{
    return (T[])items.Clone();
}

All of these methods are generic so they take a generic type parameter T that represents the type of the objects in the list or array.

The first method makes a deep clone of a list. It creates a LINQ query that iterates through the items in the list and calls the DeepClone method for each. that version of DeepClone is described in the post Clone serializable objects in C#. That code requires that the objects being serialized are serializable so this method only works if they are serializable.

An alternative strategy would be to require the type T to implement ICloneable and then invoke the object’s Clone method. Unfortunately the Clone method required by ICloneable need not be a deep clone, so the result might be a shallow clone in some cases.

The first method shown here passes the LINQ query into the new list’s constructor. That constructor can take an IEnumerable as a parameter and use it to create the items in the new list.

The second extension method is similar to the first except it works for an array instead of a list. It uses a similar LINQ query and then just calls its ToArray method to convert the items selected by the query into an array.

The third method makes shallow clones of the objects in a list. It passes the original list into the new list’s constructor. That constructor uses the items to initialize the new list.

The final method uses an array’s Clone method to make a shallow clone of the array. You could simply call that method in your own code. Here is is wrapped in the ShallowClone method for consistency with the other methods.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in algorithms, OOP, syntax and tagged , , , , , , , , , , , , , . Bookmark the permalink.

One Response to Clone lists and arrays of objects in C#

  1. E. Anderson says:

    You can greatly simplify the code and remove the loops:

    public static List DeepClone(this List items)
    {
    return new List(from x in items select x.DeepClone());
    }

    public static T[] DeepClone(this T[] items)
    {
    return (from n in items select n.DeepClone()).ToArray();
    }

    public static List ShallowClone(this List items)
    {
    return new List(items);
    }

    I’ve been playing with LINQ for about a year now and find it fascinating. My experience so far is it makes our production code less buggy — relying on the .NET framework to do the repetitive work — and easier to maintain.

Leave a Reply

Your email address will not be published. Required fields are marked *