6

我将 double[] 类型的列表传递给类中的函数,使用 tempList 编辑函数中的值,然后返回编辑后的值。但是正在传递的 originalList 也正在被编辑,我不希望它们被编辑以匹配 tempList。

这是代码。

List<double[]> newList = new List<double[]();
newList = myClass.myFunction(value, originalList);

// myClass
...

// myFunction
public List<double[]> myFunction(int value, List<double[]> myList)
{
    List<double[]> tempList = new List<double[]>();
    for (int i = 0; i < myList).Count; i++)
    {
       tempList.Add(myList[i]);
    }


    // Do stuff to edit tempList

    return tempList;
}
4

8 回答 8

4

请记住,数组是引用类型。当您将数组添加到 时tempList,只会添加对该数组的引用,因此myList两者tempList都引用相同的double[]对象。

相反,您需要克隆数组:

for (int i = 0; i < myList.Count; i++)
{
   tempList.Add((double[])myList[i].Clone());
}
于 2012-05-24T14:57:15.960 回答
1

数组 ,here double[]是引用类型,所以行

tempList.Add(myList[i]);

正在添加对原始数组的引用。然后,当您编辑 tempList 时,您正在编辑原始数组。制作这样的副本:

tempList.Add(myList[i].ToArray());
于 2012-05-24T14:57:41.143 回答
1

您将对数组的引用添加到新列表中,但不会复制每个数组的内容。您的副本应如下所示:

foreach (double[] item in myList)
{
    double[] copy = new double[item.Length];
    Array.Copy(item, copy);
    templist.Add(copy);
}
于 2012-05-24T14:59:13.373 回答
0

您遇到的问题double[]是引用类型,而不是值类型,因此当您将它添加到您的 时tempList,您添加的是对原始对象的引用,而不是新对象。您实际上需要double[]在添加之前创建一个新对象,tempList这样您就不会处理原始对象。

假设您可以使用 LINQ,则不需要循环。您可以执行以下操作:

var tempList = myList.Select(x => x.ToArray()).ToList();
于 2012-05-24T14:57:23.030 回答
0

这是因为集合/引用类型是通过引用传递的。(实际上保持变量是按值传递的,但所有变量都指向同一个引用)。

有关详细说明,请阅读此 SO Answer

如果您希望我的 Function 中的修改不反映在原始集合中,则必须复制/克隆它,然后传递给myFunction.

例子

newList = myClass.myFunction(value, (List<double>)originalList.Clone());
于 2012-05-24T14:57:31.377 回答
0
tempList.Add(myList[i]);

意味着您将对索引 i 上的 double[] 对象的引用添加到临时列表。因此,如果您编辑该对象的值,您将获得两个列表中的机会。

如果您想要一个不会相互影响的不同克隆列表,您将必须这样做:

List<double[]> tempList = new List<double[]>();
for (int i = 0; i < myList).Count; i++)
{
   double[] originalListItem = myList[i];

   // the most important step here!!! - clone the originalListItem to clonedListItem

   tempList.Add(clonedListItem);
}


// Do stuff to edit tempList

return tempList;
于 2012-05-24T14:57:47.813 回答
0

您正在将 double[] 引用复制到新列表,这是一个浅拷贝。您需要一个深拷贝并创建新的双精度数组来编辑临时数组而不更改原始数组。

于 2012-05-24T15:01:02.350 回答
0

您在 tempList 中插入对数组的引用,而不是数组的副本。因此,如果您更改 tempList 中的值,您将更改原始数组。

此代码将更好地工作:

    for (int i = 0; i < myList.Count; i++)
    {
       var copy = new Double[myList[i].Length];
       Array.Copy(myList[i], copy, myList[i].Length);
       tempList.Add(copy);
    }
于 2012-05-24T15:02:39.393 回答