Collections in C#

Collections are types that holds a set of related data object together that can be treated as a single object on which we can perform filtering/searching, modifying or add/remove data.

Arrays

Arrays are type of collection that is used to store logically related data under a single variable name.

//Declaring
int[] numbers;
string[] names;
//initializing
int[] numbers = new int[4] { 1, 4, 21, 53};
string[] names = new string[2] {"Rama", "Krishna"};

//reading based on index
var value = numbers[0];
//writing based on index
numbers[0] = 5;

//iterating
for(int i=0; i<numbers.length; i++)
{
     Console.WriteLine(numbers[i]);
}

foreach (int number in numbers)
{
    Console.WriteLine(number);
}

Syntax : int[] numbers = new int[3];

  • Arrays have a fixed size.

  • Arrays are zero-indexed.

  • Elements can be accessed based on index.

  • Can be iterated using for and foreach loops.

  • C# also supports multi-dimensional and jagged arrays.

We can also use arrays for passing variable number of arguments to a method.

public static void Sum(params int[] numbers)
{
   //implementation
}

//calling statement
Sum(3,7,21);
Sum(3,7,21,44);
Sum(3,7,21,6,54,33,234);

ArrayList

  • It is an ordered collection of an objects that can be indexed individually.

  • It's size increases/decreases automatically when items are added/removed.

  • Items can be accessed based on index.

  • We can add values of any kind into an ArrayList as it is not strongly typed.

  • It is slower in performance as elements are boxed and stored as objects.

  • Elements can be accessed based on index.

//declaration
ArrayList arrayList;
//initialization
ArrayList arrayList = new ArrayList(); 

//adding elements
arrayList.Add(12);
arrayList.Add("Rama");

//accessing elements
int firstElement = (int) arrayList[0]; //12
string secondElement = (string) arrayList[1]; //Rama

//add element at particular index
arrayList.Insert(0, "Hello");
//remove element
arrayList.Remove("Hello");
arList.RemoveAt(0); //Removes element at index 0

HashTable

  • It is a collection that stores key-value pairs based on the hash code of the key.

  • It uses the key to access the elements in the collection.

  • Keys must be unique and cannot be null.

  • Values can be null or duplicate.

  • It implements IDictionary interface.

  • Values are stored as DictionaryEntry objects.

//initialization
Hashtable hashTable = new Hashtable();
// Add elements to the Hashtable
hashTable.Add("1", 123);
hashTable.Add("2", "Hello");
hashTable.Add("3", 3.14);
//access elements by key
hashTable["1"]; //123
//iteration
foreach(DictionaryEntry dictionaryEntry in hashTable)
{
    Console.WriteLine("Key: {0}, Value: {1}", 
                        dictionaryEntry.Key, dictionaryEntry.Value);
}

SortedList

  • It is a collection used for storing key-and-value pairs that are sorted by the keys and are accessible by index using key.

  • Supports both generic and non-generic.

  • SortedList can be of any single data type even for non generic.

  • It sorts elements as soon as they are added. Sorts primitive type keys in ascending order and object keys based on IComparer<T>.

  • Keys must be unique and cannot be null.

  • Values can be null or duplicate.

  • Values are stored as KeyValuePair<TKey, TValue>objects for generic type whereas DictionaryEntry objects for non generic.

  • Retrieval is faster as elements are sorted.

  • It is similar to SortedDictionary and It uses lesser memory than SortedDictionary.

Non-generic example:

//initialization non-generic
SortedList sortedList = new SortedList()
{
    { 1, "hello" },
    { 2, "hi"}
};

SortedList sortedList = new SortedList()
{
    { 1, "hello" },
    { "hi", "hi" } //runtime exception as type is changed
};

//assign
sortedList[1] = "hello! how are you?"; // where 1 is key
//add element
sortedList.Add(2, "Bye!");
//access element
Console.WriteLine(sortedList[1]); // hello
//iteration
foreach(DictionaryEntry dictionaryEntry in sortedList)
{
    Console.WriteLine("Key: {0} | Value: {1}", 
                dictionaryEntry .Key, dictionaryEntry .Value);
}

Generic Example

//initialization
SortedList<int, string> names = new SortedList<int, string>(){{0, "Krishna"}};
//access element
Console.WriteLine(names[1]); //Sankarshan
//add elements
names.Add(1,"Sankarshan");
names.Add(4,"Ramesh");
names.Add(5, null);
//remove elements
names.Remove(1)//where 1 is key
names.RemoveAt(0);//where 0 is index
//iteration
foreach(KeyValuePair<int, string> keyValues in names)
    Console.WriteLine("key: {0} | value: {1}", keyValues.Key , keyValues.Value);

for (int i = 0; i < names.Count; i++)
{
    Console.WriteLine("key: {0} | value: {1}", names.Keys[i], names.Values[i]);
}

Dictionary

  • Dictionary is a generic collection that stores key-value pairs in no particular order and elements are accessible by index using key.

  • Implements IDictionary<TKey, TValue> interface.

  • Keys must be unique and cannot be null.

  • Values can be null or duplicate.

  • Values are stored as KeyValuePair<TKey, TValue>objects.

//initialization
var names = new Dictionary<int, string>();
//or
var names = new Dictionary<int, string>()
{
    { 1, "Sankarshan" };
    { 2, "Rama" };
}
//assign
names[4] = { "Krishna" };
names.Add( 3, "Ganesh");

//iteration
foreach(KeyValuePair<int, string> keyValues in numberNames)
{
    Console.WriteLine("Key: {0} | Value: {1}", keyValues.Key, keyValues.Value);
}

//access elements
names[1]; //Sankarshan
//with safer read to avoid key not found exception
var retrievedName = names.TryGetValue(1, out string name); 

//check if a key exists
if(names.ContainsKey(1)){  
    Console.WriteLine(names[1]);
}

//remove based on a key
names.Remove(1);

//restrict duplicate keys irrespective of case
var names = new Dictionary<int, string>(StringComparer.OrdinalIgnoreCase);

SortedDictionary

  • It is similar to dictionary but that are sorted on the key.
SortedDictionary<string, string> names =
            new SortedDictionary<string, string>();

ReadOnlyDictionary

  • It cannot be modified once it is initialized.
ReadOnlyDictionary<string, string> names =
            new ReadOnlyDictionary<string, string>
            (new Dictionary<string, string>(){{ "1", "Sankarshan" }});

List<T>

  • Generic collection

  • Resizes dynamically

Hashset<T>

  • Used to store unique elements based on hash code.

  • Faster retrieval of elements.

  • Does not support keys.

  • Contains unique values.

  • It can allow a single null value.

//initialization
var names = new HashSet<string>();
//add elements
names.Add("Sankarshan");
names.Add("Sankarshan"); // doesnt add duplicate and no exception thrown

//retrieval
names.TryGetValue("Sankarshan", out string name);
//contains
names.Contains("Sankarshan");
//remove
names.Remove("Sankarshan");
//use UnionWith() and IntersetWith() with other hashset if required

Did you find this article valuable?

Support .NET - Sankarshan Ramesh by becoming a sponsor. Any amount is appreciated!