Everything Matters
Everything Matters

Reputation: 2730

array vs generic list - storing value types - how is it stored and what happens in memory during access?

It is a simple question but I would like to understand what happens in the memory in this.

I understand converting a value type to reference type is boxing.

int I = 10;
object obj = I; // boxing - I is moved from stack to heap

1.Incase of an int array :

int[] arrInt = new int[1];
arrInt[0] = 10;
int I = arrInt[0];

Here, I know arrInt is in stack (with address to heap) and would point to heap where '10' is stored.

In this case, is 10 'boxed' and stored in heap ? or it exists as unboxed value type ? So when I access the item back, int I = arrInt[0] what happens ?

2.Incase of an int Generic List:

List<int> lstInt = new List<int>(){10};
int I = lstInt[0];

In case of generic List<int>, in the msdn documentation, it quotes, using generic collections avoids the overhead of boxing : "http://msdn.microsoft.com/en-us/library/vstudio/ms172194(v=vs.100).aspx" But I fail to understand, How is the integer value would be stored in case of List in generics ? Does it mean, it exists as unboxed ? So, in this, if I access int I = lstInt[0], what happens in this case ?

Thanks.

Upvotes: 1

Views: 393

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273274

A List<> uses an array under the covers so what happens is the same in both cases.

And when you put an int into an array it is not boxed, just copied.

int i = 10;
int j = i;    // copy contents of 'i' to 'j'
a[0] = i;     // copy contents of 'i' to 'a[0]'

The array is allocated on the heap, and when i and j are normal local variables they are on the stack. But these are considered 'implementation details'.

 myObject.X = i;  // copy contents of 'i' to 'X' 

both a[0] and X are on the heap.

Upvotes: 2

Steven
Steven

Reputation: 172666

In this case, is 10 'boxed' and stored in heap ? or it exists as unboxed value type ?

The value is not boxed, since you defined an array of type int[].

So when I access the item back, int I = arrInt[0] what happens ?

The value is in that case directly read from the memory location inside the array. No unboxing happens. Just a simple copy of a 32 bit value.

But I fail to understand, How is the integer value would be stored in case of List in generics ?

In the background, List<T> internally stored the values in a T[] array. So there's no boxing boing on there. If you decompile the List<T> class, you'll see that its Items property (the indexer) looks something like this:

public T this[int index]
{
    get
    {
        if (index >= this._size) ThrowHelper.ThrowArgumentOutOfRangeException();
        return this._items[index];
    }
    set
    {
        if (index >= this._size) ThrowHelper.ThrowArgumentOutOfRangeException();
        this._items[index] = value;
        this._version++;
    }
}

Here, the _items instance field is defined as follows:

private T[] _items;

using generic collections avoids the overhead of boxing

It avoids the overhead of boxing compared to the non-generic versions such as ArrayList. ArrayList uses an object[] array in the background which causes value types to be boxed.

Upvotes: 5

Related Questions