Do containers of primitive types in C# use value semantics or pointer/reference semantics?
c#
Solution
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.)
Problem
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>>`?