Collections In .NET

Why a Collection?

  • Array size is fixed and cannot be increased dynamically.  However, in actual development scenarios, the same type of objects are needed to be processed and added dynamically, and the size of the unit holding the objects should grow or shrink accordingly. This functionality is provided in Collections.
  • The insertion and deletion of elements in an array are also costly in terms of performance.
  • Also, the way these objects should be stored can be different, there can be a requirement to store the objects sequentially, non-sequentially, sorted order, etc.
  • Collections come in handy as a return type in the implementation of business methods, generally, when data is obtained from a file or database, it can be a single or multiple objects. When one is not sure, it is safe to define return type as a collection since it can hold multiple objects. This works even if a single or no object is returned.

Introduction

  • A collection is a set of similar types of objects that are grouped together.
  • System.Collections namespace contains specialized classes for storing and accessing the data.
  • Each collection class defined in .NET has a unique feature.

Collection Interfaces

 
There are some basic operations that are possible on any collection.
  1. Search specific objects in the collection.
  2. Adding or removing objects dynamically in the collection.
  3. List the objects in the collection by iterating through it. And so on
These basic operations are defined in the form of interfaces. All the collection classes implement these interfaces to get the required functionality. The implementation can be different for different classes. For example, adding objects in an Array is different than adding objects in an ArrayList collection. ArrayList grows and shrinks dynamically. Both the collections need the functionality of iteration using a foreach loop to display the list of objects contained in them.
 
Types of collections
 
.net collection types
  • Arrays
     
    Array class is defined in System namespace. Arrays can store any type of data but only one type at a time. The size of the array has to be specified at compilation time. Insertion and deletion reduce performance.
  • Advanced Collections
     
    Many times we can’t give number elements in the list and we need to perform different operations like inserting, deleting, sorting, searching, comparing, and so on. To perform these operations efficiently, the data needs to be organized in a specific way. This gives rise to advanced collections. Advanced collections are found in System.Collections namespace.
Advanced collections are again divided into two types-
 

Non-generic collections

Every element in the non-generic collection is stored as a System.Object type.
 
Examples
 
ArrayList, Stack, Queue, HashTable, and so on.
  • Boxing
     
    Conversion of value type to a reference type is known as boxing. When the value is boxed, CLR allocates a new object on the heap and copies the value of the value type into that instance. CLR returns a reference of newly created objects. This is essentially an upcast as all types are derived from System.Object class. Developers need not use wrapper classes or structures for value types to perform the conversion.
     
    Example
    1. int speed =80  
    2. Object obj= speed;   
  • Unboxing
     
    It is an opposite operation of boxing, that is copied from a reference type to a value type on the stack. Explicit casting is required as it is downcast. It is the conversion of a derived type to a base type.
     
    Example
    1. int speed =80  
    2. Object obj= speed // boxing  
    3. int speed=(int) obj // unboxing   

Generic collections

 
These are defined in System.Collections.Generic namespace.
 
Examples
 
Generic list, generic queue, and so on. They are template-based versions of their counterparts.
 
Generics help to define generic functions or classes which avoid repetition of code for different data types. Generic collections are very useful when implementing generic constructs like searching, sorting, stacks, queues, lists, vectors, and so on. These constructs have a generic algorithm that can be implemented for any data type.
 
Data Type has to be specified at the time of instantiation of generic classes, thus providing type safety. For example, the int data type is specified to instantiate the ArrayList class. The methods of HashTable class also take a parameter of type K. K is a placeholder. The compiler generates type-specific implementation. The compiler does not create a brand new implementation of the generic type. It addresses only those methods and properties of the generic type that are actually invoked. Boxing, unboxing, and casting are not required as the stored elements in the generic collection are of the specified type. 
 
Some of the types of classes in the generic collection are,
 
generic collection class
 
Advantages of generic collections
  • No boxing and type casts are required, thereby improves the performance of the application.
  • Type errors are detected at compile-time, thus avoids runtime errors.
  • Generic code once is written can be reused by instantiating the class with a specific type.