codeless
codeless

Reputation: 63

List<int[]> is populated only by last contents of int[]

I am testing how to get multiple data returned from a function. I was trying to use a List of int[]. To do this I have a function that returns a List<int[]>, which is shown below:

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;
}

When i check the contents of the list, I see that it contains 2 records but they both contain the last records of the int[]. Which means that instead of

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

I get

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

I was wondering why this is happening.

Upvotes: 2

Views: 147

Answers (4)

Ramesh Rajendran
Ramesh Rajendran

Reputation: 38663

Because you have override the reference and add that into the list. if you assign the values into a new reference then you can get what you want.

try this

 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;
}

Upvotes: 0

Aaron Christiansen
Aaron Christiansen

Reputation: 11807

testlist.Add(record) is adding a reference to record to the testlist array.

In other words, you aren't adding two separate arrays to testlist; you're adding a reference to the same array, record, twice.

This means that, if you modify record after adding it to the list, it updates inside the list too. testlist doesn't contain 'actual arrays', it contains a pointer to an array. In this case, that pointer is to record.

You could fix this by introducing a new array:

 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;
}

Then your list contains two different objects, rather than two references to the same one.

To learn more about this, you should Google and read about pass-by-reference and pass-by-value. C# uses pass-by-reference for most function parameters, with the notable exceptions being basic numeric types (e.g. int and float) and structs.

Upvotes: 0

Mong Zhu
Mong Zhu

Reputation: 23732

The problem is that you have only one instance of int[] record which you place twice into your list. An array is a reference type. The documentation states:

With reference types, two variables can reference the same object; therefore, operations on one variable can affect the object referenced by the other variable.

In the second run you overwrite the values of the first one, because record still refers to the same object. This is why you have the same values in both arrays.

To solve it you need to create a brand new instance for every entry in the list:

 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;
}

For more information on Reference and Value-Types please read this article

Upvotes: 1

Georg Patscheider
Georg Patscheider

Reputation: 9463

Arrays, e.g. int[] are reference types. So when you assign 11 to the first cell of the array, you are overwriting the 1 that was originally in this cell. Because your List<int[]> only holds a reference to the array, the value is changed there as well.

Instead, assign a copy of the array to the list to break these references:

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;

Or do not reuse the same array:

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;

Further reading: Difference between a Value Type and a Reference Type

Upvotes: 0

Related Questions