11)ArrayList
11)ArrayList
// C# has some inbuilt list type data structures – ArrayList is one of them. It is a part of the System.Collections namespace.
// ArrayList is an untyped dynamically-extendable array. Unlike arrays, which have a fixed size, ArrayList can dynamically grow or shrink as
elements are added or removed - implemented similarly to the static list implementation.
// Dynamic : When you add an element, ArrayList checks if the current size equals the capacity. If the size equals the capacity, the ArrayList
needs to resize. It typically doubles its capacity to accommodate new elements, which minimizes the number of resizing operations needed
when adding many elements. This is probably internally done by allocating a new array buffer with a larger capacity (usually double the
current size), copying the elements from the old array buffer to the new one, then replacing the reference to the old array buffer with the
new one.
// Untyped: ArrayList stores its elements in an array (so contiguous memory locations) of type object. Since all types in C# ultimately derive
from the object class, this allows ArrayList to hold any type of data, including value types (like int, double, etc.) and reference types (like
string, custom classes, etc.).
// Boxing, Unboxing : When you add a value type to an ArrayList, it is automatically boxed, which means it is wrapped in an object
reference. This can introduce some overhead (make code slow) due to boxing and unboxing.
// Know that there are two types of storage a process has, the stack and the heap. Value types are typically stored on the stack and
reference types on the heap. Pushing and popping the stack is fast, no garbage collection is required either. For reference types, not only
does memory need to be allocated by the runtime but the GC must be made aware of them as well for managing them.Boxing is used to
store value types in the garbage-collected heap.
// Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value
type allocates an object instance on the heap and copies the value into the new object. Boxing and unboxing are computationally expensive
processes. When a value type is boxed, a new object must be allocated and constructed. Later when you pull it out, the value is copied out
and put on the stack. Boxing is necessary when you need to pass a value type to a method that expects an object reference. For example, if
you want to add an integer value to an ArrayList, which only accepts objects, we need to box the integer value before adding it to the
ArrayList. (done by inbuilt boxing)
Unboxing is necessary when you need to retrieve the original value type from an object reference. For example, if you retrieve an integer
value from an ArrayList, which only stores objects, you need to unbox the object reference before using it as an integer.