Generic Collections and Their Initialization
Generic collections can greatly improve the quality of your application, while also reducing the size of your program.
Aug 15, 2019 • 6 Minute Read
Introduction
As programming languages came to live there was usually a common requirement among them. People wanted to store data in a structured way, to later in time retrieve and manipulate it. There were generic operations which were commonly performed on these datasets.
Operations:
- Add, remove
- Find, sort, search
- Replace
- Copy, clone,
- Number of elements stored
C# and .NET are no exception in this situation either. There are basically two types of collections that are provided with the framework to your disposal.
Collections:
- Generic
- Non-generic
Prior to .NET v2.0, there were only collections.
Non-generic collections:
- ArrayList
- HashTable
- SortedList
- Stack
- Queue
Generic collections:
- List
- Dictionary
- SortedList
- Stack
- Queue
The main difference between generic and non-generic collections is the value of types that they can store. In a non-generic collection, each element can represent a value of a different type, and the collection size is not fixed. This means, at a later time, items can be added or removed.
Utilizing Generics
In order to harness the facilities provided by generics, we need to add the following line to the top of our application.
using System.Collections.Generic;
This allows us to refer to a generic List data structure with the following initialization.
List<int> myList = new List<int>(10);
Without the using statement we would need to specify the fully qualified path to the class or data structure.
System.Collections.Generic.List<int> myList = System.Collections.Generic.List<int>(10);
The using statement allows you to import other classes and libraries to your actual namespace. Thus, reducing codebase and making developers to code more easy to understand.
Non-generic HashTable
Hashtables are made up of key and value pairs of a specific type. As per the general requirement, this data structure supports many types of operations. You can add, remove, find, replace, etc... anything that you put into this hashtable.
static void Main(string[] args)
{
Hashtable myHash = new Hashtable();
myHash.Add("Pluralsight", "is the first!");
myHash.Add(2, "is the most cool language!");
myHash.Add(-3.0, "is really fun!");
foreach (DictionaryEntry d in myHash)
Console.WriteLine(d.Key + " " + d.Value);
Console.ReadLine();
}
The output will be something like this.
2 is the coolest language!
Pluralsight is the first!
-3.0 is really fun!
Note that the hashtable does not preserve the order of insertion. This means the foreach can produce the above output after each consecutive run.
Generic ArrayList
The properties of generic arraylist allow you to store arbitrary types of values in a list that is ever-expanding. You can add and remove elements to this list, as many as you like. The following code block shows you how to initialize an ArrayList, add items, iterate over the items, or even remove items that you do not feel are worth having. You could also get the number of items held in the list at any given moment.
static void Main(string[] args)
{
ArrayList myArray = new ArrayList();
myArray.Add(1);
myArray.Add(2);
myArray.Add("Pluralsight");
myArray.Add("Written guide!");
foreach (object element in myArray)
Console.WriteLine($"The array list: {element}");
Console.WriteLine($"There are a total of {myArray.Count} element(s) in myArray!");
myArray.Remove(1);
Console.WriteLine($"There are a total of {myArray.Count} element(s) in myArray!");
}
The output from our execution is as follows. We put four items on our list, get the count of elements, remove one element, and then get the count of the elements once again.
The array list: 1
The array list: 2
The array list: Pluralsight
The array list: Written guide!
There are a total of 4 element(s) in myArray!
There are a total of 3 element(s) in myArray!
Boxing and Unboxing
This concept is very important when you are working with generics in C# in general. The concept and its realization provide some of the benefits of the strongly-typed collections as well as providing higher quality and a performance boost to the code.
There are two major categories for the data type in C#, one is called value type the other is called reference type. Boxing is the process of converting a value type to a reference type. Behind the scenes, the CLR allocates a new object into the heap. Then it copies the value type's value into that instance.
An example of this is the following.
int b = 99;
object b = a;
int c = (int)b;
The first line gives us the variable b with an explicit integer type and the value of 99. The second line converts it to reference type, and copies its value. The last line gives us back the value 99 with the c value type. When the C# compiler sees the assignment from int to object, and vice-versa, it automatically inserts the corresponding box and unbox statements.
Behind the scenes, this activity is related to how the generic and non-generic collections are handled in C#.
Conclusion
All in all Generic and Non-Generic collections are a nice built-in toolset in .NET and C# as well. Being aware of the functionality and the facilities they provide can greatly improve the quality of your application, while also reducing the size of your program. These toolsets were collected over time as general purpose, third-party implementations got more and more popular they were incorporated into the .NET framework to unify and standardize the source of these classes, functions, and data structures/types. I hope you were able to find what you were looking for.