C#按值复制数组

JOB*_*OBG 16 c# arrays

我有一个类型数组MyType[] types; ,我想制作和独立的数组副本.我试过这个

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

types2 = types ;
Run Code Online (Sandbox Code Playgroud)

但这会创建对第一个的引用.然后我试过了

Array.Copy( types , types2 , types.Length ) ;
Run Code Online (Sandbox Code Playgroud)

但我有同样的问题:更改第一个数组中的值也会更改副本中的值.

如何制作数组,IList或IEnumerable的完全独立或深层副本?

Sam*_*ell 13

基于第一篇文章,他所需要的只是"数组的独立副本".对shallowCopy数组本身的更改不会出现在types数组中(意思是元素赋值,这实际上是他在上面展示的内容,尽管说"深拷贝").如果这符合您的需求,它将具有最佳性能.

MyType[] shallowCopy = (MyType[])types.Clone();
Run Code Online (Sandbox Code Playgroud)

他还提到了一个"深层复制",它对于不是基元的递归值类型聚合的可变类型会有所不同.如果是MyType工具ICloneable,这适用于深层复制:

MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());
Run Code Online (Sandbox Code Playgroud)


eul*_*rfx 9

在MyType上实现克隆方法,使用受保护的方法MemberwiseClone(执行浅拷贝)或使用深度克隆技术.您可以让它实现ICloneable然后编写几个扩展方法来克隆相应的集合.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须执行此操作,因为在使用Array.Copy时创建新数组时,它会复制引用,而不是引用的对象.每种类型都负责复制自己.


hel*_*ker 9

对于不耐烦:

newarray = new List<T>(oldarray).ToArray();
Run Code Online (Sandbox Code Playgroud)


Fre*_*örk 7

如果您的类型是可序列化的,则可以使用序列化技术获取数组的副本(包括项目的深层副本):

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它:

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

MyType[] copies = (MyType[])GetCopy(items);
Run Code Online (Sandbox Code Playgroud)