复制2d数组列表

时间:2016-02-25 03:18:52

标签: c# list multidimensional-array

我有一个列表List<MyClass>[,] myarraylist;并且已填充。

我想将其复制到List<MyClass>[,] mycopy,然后更改mycopy而不更改myarraylist

这样做最快的方法是什么?

3 个答案:

答案 0 :(得分:2)

这取决于你真正想做的事情。您可以轻松克隆阵列:

List<MyClass> mcopy = new List<MyClass>[marraylist.GetUpperBound(0)+1,marraylist.GetUpperBound(1)+1];
for (int i = 0; i < marraylist.GetUpperBound(0); ++i)
{
    for (int j = 0; j < marraylist.GetUpperBound(1); ++j)
    {
        mcopy[i,j] = marraylist[i,j];
    }
}

现在,它为您提供了数组的副本。但是,mcopy[1,2]引用了与marraylist[1,2]相同的列表。如果您修改该列表,那就是您要编写:

mcopy[1,2].Add(new MyClass(...));

然后,这也将修改marraylist[1,2]中引用的列表。

如果要创建列表的副本,则内部循环中的代码必须为:

mcopy[i,j] = new List<MyClass>(marraylist[i,j]);

这会创建一个新列表,因此如果您在mcopy[1,2]修改列表,则不会修改原始数组中的列表。

但这也许不是你想要的。因为尽管mcopy[1,2]包含的列表与marraylist[1,2]不同,但列表具有相同的内容。因此,如果你写了mcopy[1,2][1].SomeProperty = 42;,那么你也会在marraylist[1,2][1]修改对象的内容,因为它们是同一个对象。

如果要复制对象的列表和副本,那么内部循环代码将变为:

mcopy[i,j] = marraylist[i,j].Select(m => new MyClass(/* create from m */)).ToList();

/* create from m */注释意味着您要么将m传递给复制构造函数(如果有的话),要么传递单个参数,或者如果您在类上有克隆方法,那么用那个。不知何故,您想要制作MyClass实例的深层副本。

是的,这很复杂。 “复制”这个词在这里非常重载,你如何继续完全取决于你正在使用的“复制”的定义。是否要复制数组(仅复制引用),数组的内容(使用相同的对象创建新列表)或列表的内容(使用包含相同数据的新对象创建新列表)?< / p>

答案 1 :(得分:0)

如果MyClass有一个拷贝构造函数:

var newList = new List<MyClass>[oldList.GetLength(0), oldList.GetLength(1)];

for (int i = 0; i < oldList.GetLength(0); i++)
    for (int j = 0; j < oldList.GetLength(1); j++)
        newList[i, j] = oldList[i, j].Select(x => new MyClass(x)).ToList();

如果它没有复制构造函数,并且您无法添加复制构造函数,则必须编写自己的函数来制作MyClass的副本。

newList[i, j] = oldList[i, j].Select(x => CloneMyClass(x)).ToList();

答案 2 :(得分:0)

这可能有效。它是2D IEnumerables的扩展方法。这意味着它可以与实现IEnumerable接口的任何对象一起使用,只要您的类T实现ICloneable即可。

public static IEnumerable<IEnumerable<T>> Clone<T>(this IEnumerable<IEnumerable<T>> twoDList) where T : ICloneable
        {
            if (twoDList != null)
            {
                List<List<T>> result = new List<List<T>>();
                for (int i = 0; i < twoDList.Count(); i++)
                {
                    List<T> aList = new List<T>();
                    for (int j = 0; j < twoDList.ElementAt(i).Count(); j++)
                    {
                        aList.Add(twoDList.ElementAt(i).ElementAt(j));
                    }
                    result.Add(aList);
                }
                return result;
            }
            else
            {
                return null;
            }
        }

它还应该与实现IEnumerable的锯齿状2D结构一起使用。 用法示例如下:

List<List<MyClass>> cloned = original2DStructure.Clone();

可以在here上找到有关使类实现ICloneable的帮助。