C# Copy Array by Value

Based on the first post, all he needs is this for "an independent copy of the array". Changes to the shallowCopy array itself would not appear in the types array (meaning element assignment, which really is what he showed above despite saying "deep copy"). If this suits your needs, it will have the best performance.

MyType[] shallowCopy = (MyType[])types.Clone();

He also mentions a "deep copy" which would be different for mutable types that are not recursive value-type aggregates of primitives. If the MyType implements ICloneable, this works great for a deep copy:

MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());

For the impatient:

newarray = new List<T>(oldarray).ToArray();

Implement a clone method on MyType, using protected method MemberwiseClone (performs shallow copy) or using a deep cloning technique. You can have it implement an ICloneable then write several extensions methods that will clone the corresponsing collection.

interface ICloneable<T>
{
    T Clone();
}

public static class Extensions
{
    public static T[] Clone<T>(this T[] array) where T : ICloneable<T>
    {
        var newArray = new T[array.Length];
        for (var i = 0; i < array.Length; i++)
            newArray[i] = array[i].Clone();
        return newArray;
    }
    public static IEnumerable<T> Clone<T>(this IEnumerable<T> items) where T : ICloneable<T>
    {
        foreach (var item in items)
            yield return item.Clone();
    }
}

You must do this because while a new array is created when you use Array.Copy it copies the references, not the objects referenced. Each type is responsible for copying itself.


If your type is serializable you can use serialization techniques to get a copy of your array (including deep copies of the items):

private static object GetCopy(object input)
{
    using (MemoryStream stream = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, input);
        stream.Position = 0;
        return formatter.Deserialize(stream);
    }
}

To use it:

MyType[] items = new MyType[2];
// populate the items in the array

MyType[] copies = (MyType[])GetCopy(items);