List <int []>仅由int []的最后一个内容填充

时间:2018-03-07 10:25:16

标签: c# list int

我正在测试如何从函数返回多个数据。我试图使用int[]列表。为此,我有一个返回List<int[]>的函数,如下所示:

private List<int[]> Test()
{
        List<int[]> testlist = new List<int[]>();
        int[] record = new int[3];
        record[0] = 1;
        record[1] = 2;
        record[2] = 3;
        testlist.Add(record);
        record[0] = 11;
        record[1] = 12;
        record[2] = 13;
        testlist.Add(record);
        return testlist;
}

当我检查列表的内容时,我看到它包含2条记录,但它们都包含int[]的最后记录。这意味着而不是

list[0] = {1,2,3}
list[1] = {11,12,13}

我得到了

list[0] = {11,12,13}
list[1] = {11,12,13}

我想知道为什么会这样。

4 个答案:

答案 0 :(得分:1)

问题是您只有一个int[] record个实例,您可以将其放入列表中两次。数组是reference type。文档说明:

  

对于引用类型,两个变量可以引用同一个对象;因此,对一个变量的操作可能会影响另一个变量引用的对象。

在第二次运行中,您将覆盖第一次运行的值,因为record仍然引用同一个对象。这就是为什么在两个数组中都有相同的值。

要解决此问题,您需要为列表中的每个条目创建一个全新的实例:

 private List<int[]> Test()
{
    List<int[]> testlist = new List<int[]>();
    int[] record = new int[3];
    record[0] = 1;
    record[1] = 2;
    record[2] = 3;
    testlist.Add(record);

    int[] record2 = new int[3];
    record2[0] = 11;
    record2[1] = 12;
    record2[2] = 13;
    testlist.Add(record2);
    return testlist;
}

有关参考和价值类型的更多信息,请阅读this article

答案 1 :(得分:0)

因为您已覆盖引用并将其添加到列表中。如果您将值分配给新的参考,那么您可以得到您想要的。

试试这个

 private List<int[]> Test()
{
        List<int[]> testlist = new List<int[]>();
        int[] record = new int[3];
        record[0] = 1;
        record[1] = 2;
        record[2] = 3;
        testlist.Add(record);
        record = new int[3];// create new reference
        record[0] = 11;
        record[1] = 12;
        record[2] = 13;
        testlist.Add(record);
        return testlist;
}

答案 2 :(得分:0)

testlist.Add(record)正在向record数组中添加引用 {/ 1}}。

换句话说,您不能向testlist添加两个单独的数组;您将同一个数组testlist的引用添加两次。

这意味着,如果在将record添加到列表后进行修改,它也会在列表中更新。 record不包含&#39;实际数组&#39;,它包含一个指针到数组。在这种情况下,该指针指向testlist

你可以通过引入一个新数组来解决这个问题:

record

然后你的列表包含两个不同的对象,而不是两个对同一个对象的引用。

要了解有关此内容的更多信息,您应该在Google上阅读传递引用按值传递。 C#对大多数函数参数使用pass-by-reference,但值得注意的例外是基本数字类型(例如 private List<int[]> Test() { List<int[]> testlist = new List<int[]>(); int[] record = new int[3]; record[0] = 1; record[1] = 2; record[2] = 3; testlist.Add(record); int[] record2 = new int[3]; record2[0] = 11; record2[1] = 12; record2[2] = 13; testlist.Add(record2); return testlist; } int)和结构。

答案 3 :(得分:0)

阵列,例如int[]是引用类型。 因此,当您将11分配给数组的第一个单元格时,您将覆盖此单元格中最初的1。由于您的List<int[]>仅包含对数组的引用,因此该值也会更改。

相反,将数组的副本分配给列表以打破这些引用:

List<int[]> testlist = new List<int[]>();

int[] record = new int[3];
record[0] = 1;
record[1] = 2;
record[2] = 3;
testlist.Add(record.ToArray()); // LINQ ToArray will create a copy

record[0] = 11;
record[1] = 12;
record[2] = 13;
testlist.Add(record.ToArray()); // LINQ ToArray will create a copy

return testlist;

或者不要重复使用相同的数组:

List<int[]> testlist = new List<int[]>();
int[] record1 = new int[3];
record1[0] = 1;
record1[1] = 2;
record1[2] = 3;
testlist.Add(record1);

int[] record2 = new int[3];
record2[0] = 11;
record2[1] = 12;
record2[2] = 13;
testlist.Add(record2);

return testlist;

进一步阅读:Difference between a Value Type and a Reference Type