Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Copy Array by Value

Tags:

arrays

c#

I have a typed array MyType[] types; and i want to make and independant copy of this array. i tried this

MyType[] types2 = new MyType[types.Length] ;

types2 = types ;

but this create a reference to the first. I then tried

Array.Copy( types , types2 , types.Length ) ;

but I have the same problem: changing a value in the first array changes the value in the copy as well.

How can I make a completely independent or deep copy of an Array, IList or IEnumerable?

like image 284
JOBG Avatar asked Jul 31 '09 22:07

JOBG


3 Answers

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()); 
like image 86
Sam Harwell Avatar answered Sep 23 '22 11:09

Sam Harwell


For the impatient:

newarray = new List<T>(oldarray).ToArray();
like image 29
heltonbiker Avatar answered Sep 25 '22 11:09

heltonbiker


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.

like image 45
eulerfx Avatar answered Sep 24 '22 11:09

eulerfx