Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do containers of primitive types in C# use value semantics or pointer/reference semantics?

Tags:

c#

When a List<> of primitive types is created in C# (e.g. a List<int>), are the elements inside the list stored by value, or are they stored by reference?

In other words, is C# List<int> equivalent to C++ std::vector<int> or to C++ std::vector<shared_ptr<int>>?


1 Answers

A List<int> will have an int[] internally. No boxing is required usually - the values are stored directly in the array. Of course if you choose to use the List<T> as a non-generic IList, where the API is defined in terms of object, that will box:

List<int> list1 = new List<int>();

// No boxing or unboxing here
list1.Add(5);
int x = list1[0];

// Perfectly valid - but best avoided
IList list2 = new List<int>();

// Boxed by the caller, then unboxed internally in the implementation
list2.Add(5);

// Boxed in the implementation, then unboxed by the caller
int y = (int) list2[0];

Note that the phrase "stored by reference" is a confusing one - the term "by reference" is usually used in the context of parameter passing where it's somewhat different.

So while a List<string> (for example) contains an array where each element value is a reference, in a List<int> each element value is simply an int. The only references involved are the callers reference to the List<int>, and the internal reference to the array. (Array types themselves are always reference types, even if the element type is a value type.)

like image 58
Jon Skeet Avatar answered May 04 '26 23:05

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!