Mastering C#: Unraveling the Concepts of C# & OOPS

Prasoon AbhinawPrasoon Abhinaw
7 min read

What is List<T>

The List<T> is a collection of strongly typed objects that can be accessed by index and having methods for sorting, searching, and modifying list. It is the generic version of the ArrayList that comes under System.Collections.Generic namespace.

List<T> Characteristics

  • List<T> equivalent of the ArrayList, which implements IList<T>.

  • It comes under System.Collections.Generic namespace.

  • List<T> can contain elements of the specified type. It provides compile-time type checking and doesn't perform boxing-unboxing because it is generic.

  • Elements can be added using the Add(), AddRange() methods or collection-initializer syntax.

  • Elements can be accessed by passing an index e.g. myList[0]. Indexes start from zero.

  • List<T> performs faster and less error-prone than the ArrayList.

Create List and adding items

List<int> primeNumbers = new List<int>();
primeNumbers.Add(1); // adding elements using add() method
primeNumbers.Add(3);
primeNumbers.Add(5);
primeNumbers.Add(7);

var cities = new List<string>();
cities.Add("New York");
cities.Add("London");
cities.Add("Mumbai");
cities.Add("Chicago");
cities.Add(null);// nulls are allowed for reference type list

//adding elements using collection-initializer syntax
var bigCities = new List<string>()
                    {
                        "New York",
                        "London",
                        "Mumbai",
                        "Chicago"                    
                    };

Add Custom Class Objects in List

var students = new List<Student>() { 
                new Student(){ Id = 1, Name="Bill"},
                new Student(){ Id = 2, Name="Steve"},
                new Student(){ Id = 3, Name="Ram"},
                new Student(){ Id = 4, Name="Abdul"}
            };

Adding an Array in a List

string[] cities = new string[3]{ "Mumbai", "London", "New York" };
var popularCities = new List<string>();
// adding an array in a List
popularCities.AddRange(cities);
var favouriteCities = new List<string>();
// adding a List 
favouriteCities.AddRange(popularCities);

Accessing a List

List<int> numbers = new List<int>() { 1, 2, 5, 7, 8, 10 };
Console.WriteLine(numbers[0]); // prints 1
Console.WriteLine(numbers[1]); // prints 2
Console.WriteLine(numbers[2]); // prints 5
Console.WriteLine(numbers[3]); // prints 7

// using foreach LINQ method
numbers.ForEach(num => Console.WriteLine(num + ", "));//prints 1, 2, 5, 7, 8, 10,

// using for loop
for(int i = 0; i < numbers.Count; i++){
    Console.WriteLine(numbers[i]);
}

Accessing a List using LINQ

var students = new List<Student>() { 
                new Student(){ Id = 1, Name="Bill"},
                new Student(){ Id = 2, Name="Steve"},
                new Student(){ Id = 3, Name="Ram"},
                new Student(){ Id = 4, Name="Abdul"}
            };

//get all students whose name is Bill
var result = from s in students
         where s.Name == "Bill"
         select s;

foreach(var student in result){
    Console.WriteLine(student.Id + ", " + student.Name);
}

Insert Elements in List

var numbers = new List<int>(){ 10, 20, 30, 40 };
numbers.Insert(1, 11);// inserts 11 at 1st index: after 10.
foreach (var num in numbers){
    Console.Write(num);
}

Remove Elements from List

var numbers = new List<int>(){ 10, 20, 30, 40, 10 };
numbers.Remove(10); // removes the first 10 from a list
numbers.RemoveAt(2); //removes the 3rd element (index starts from 0)
//numbers.RemoveAt(10); //throws ArgumentOutOfRangeException

foreach (var el in intList){
    Console.Write(el); //prints 20 30;
}

Check Elements in List:

Use the Contains() method to determine whether an element is in the List<T> or not.

var numbers = new List<int>(){ 10, 20, 30, 40 };
numbers.Contains(10); // returns true
numbers.Contains(11); // returns false
numbers.Contains(20); // returns true

List<T> Class Properties and Methods:

The following table lists the important properties and methods of List<T> class:

PropertyUsage
ItemsGets or sets the element at the specified index
CountReturns the total number of elements exists in the List<T>
MethodUsage
AddAdds an element at the end of a List<T>.
AddRangeAdds elements of the specified collection at the end of a List<T>.
BinarySearchSearch the element and returns an index of the element.
ClearRemoves all the elements from a List<T>.
ContainsChecks whether the specified element exists or not in a List<T>.
FindFinds the first element based on the specified predicate function.
ForeachIterates through a List<T>.
InsertInserts an element at the specified index in a List<T>.
InsertRangeInserts elements of another collection at the specified index.
RemoveRemoves the first occurrence of the specified element.
RemoveAtRemoves the element at the specified index.
RemoveRangeRemoves all the elements that match the supplied predicate function.
SortSorts all the elements.
TrimExcessSets the capacity to the actual number of elements.
TrueForAllDetermines whether every element in the List<T> matches the conditions defined by the specified predicate.

Dictionary<TKey, TValue>

The Dictionary<TKey, TValue> is a generic collection that stores key-value pairs in no particular order.

Dictionary Characteristics

  • Dictionary<TKey, TValue> stores key-value pairs.

  • Comes under System.Collections.Generic namespace.

  • Implements IDictionary<TKey, TValue> interface.

  • Keys must be unique and cannot be null.

  • Values can be null or duplicate.

  • Values can be accessed by passing associated key in the indexer e.g. myDictionary[key]

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

Creating a Dictionary

IDictionary<int, string> numberNames = new Dictionary<int, string>();
numberNames.Add(1,"One"); //adding a key/value using the Add() method
numberNames.Add(2,"Two");
numberNames.Add(3,"Three");

//The following throws run-time exception: key already added.
//numberNames.Add(3, "Three"); 

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

//creating a dictionary using collection-initializer syntax
var cities = new Dictionary<string, string>(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

foreach(var kvp in cities){
    Console.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);
}

Access Dictionary Elements:

var cities = new Dictionary<string, string>(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

Console.WriteLine(cities["UK"]); //prints value of UK key
Console.WriteLine(cities["USA"]);//prints value of USA key
//Console.WriteLine(cities["France"]); // run-time exception: Key does not exist

//use ContainsKey() to check for an unknown key
if(cities.ContainsKey("France")){  
    Console.WriteLine(cities["France"]);
}

//use TryGetValue() to get a value of unknown key
string result;

if(cities.TryGetValue("France", out result))
{
    Console.WriteLine(result);
}

//use ElementAt() to retrieve key-value pair using index
for (int i = 0; i < cities.Count; i++)
{
    Console.WriteLine("Key: {0}, Value: {1}", 
                                            cities.ElementAt(i).Key, 
                                            cities.ElementAt(i).Value);
}

Update Dictionary

var cities = new Dictionary<string, string>(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

cities["UK"] = "Liverpool, Bristol"; // update value of UK key
cities["USA"] = "Los Angeles, Boston"; // update value of USA key
//cities["France"] = "Paris"; //throws run-time exception: KeyNotFoundException

if(cities.ContainsKey("France")){
    cities["France"] = "Paris";
}

Remove Elements in Dictionary

var cities = new Dictionary<string, string>(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

cities.Remove("UK"); // removes UK 
//cities.Remove("France"); //throws run-time exception: KeyNotFoundException

if(cities.ContainsKey("France")){ // check key before removing it
    cities.Remove("France");
}

cities.Clear(); //removes all elements

Hashtable

The Hashtable is a non-generic collection that stores key-value pairs, similar to generic Dictionary<TKey, TValue> collection. It optimizes lookups by computing the hash code of each key and stores it in a different bucket internally and then matches the hash code of the specified key at the time of accessing values.

Hashtable Characteristics

  • Hashtable stores key-value pairs.

  • Comes under System.Collections namespace.

  • Implements IDictionary interface.

  • Keys must be unique and cannot be null.

  • Values can be null or duplicate.

  • Values can be accessed by passing associated key in the indexer e.g. myHashtable[key]

  • Elements are stored as DictionaryEntry objects.

Creating a Hashtable

Hashtable numberNames = new Hashtable();
numberNames.Add(1,"One"); //adding a key/value using the Add() method
numberNames.Add(2,"Two");
numberNames.Add(3,"Three");

//The following throws run-time exception: key already added.
//numberNames.Add(3, "Three"); 

foreach(DictionaryEntry de in numberNames){
    Console.WriteLine("Key: {0}, Value: {1}", de.Key, de.Value);
}

//creating a Hashtable using collection-initializer syntax
var cities = new Hashtable(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

foreach(DictionaryEntry de in cities){
    Console.WriteLine("Key: {0}, Value: {1}", de.Key, de.Value);
}

Add Dictionary in Hashtable

Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "one");
dict.Add(2, "two");
dict.Add(3, "three");

Hashtable ht = new Hashtable(dict);

Update Hashtable

//creating a Hashtable using collection-initializer syntax
var cities = new Hashtable(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

string citiesOfUK = (string) cities["UK"]; //cast to string
string citiesOfUSA = (string) cities["USA"]; //cast to string

Console.WriteLine(citiesOfUK);
Console.WriteLine(citiesOfUSA);

cities["UK"] = "Liverpool, Bristol"; // update value of UK key
cities["USA"] = "Los Angeles, Boston"; // update value of USA key

if(!cities.ContainsKey("France")){
    cities["France"] = "Paris";
}

Remove Elements in Hashtable

var cities = new Hashtable(){
    {"UK", "London, Manchester, Birmingham"},
    {"USA", "Chicago, New York, Washington"},
    {"India", "Mumbai, New Delhi, Pune"}
};

cities.Remove("UK"); // removes UK 
//cities.Remove("France"); //throws run-time exception: KeyNotFoundException

if(cities.ContainsKey("France")){ // check key before removing it
    cities.Remove("France");
}

cities.Clear(); //removes all elements

Thanks for your time. I hope this post was helpful and gave you a mental model for List, Dictionay & HashTable in C#!

0
Subscribe to my newsletter

Read articles from Prasoon Abhinaw directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prasoon Abhinaw
Prasoon Abhinaw

I am a passionate software engineer with over 16 years of hands-on experience in the tech industry. On this blog, I aim to share my expertise, insights, and love for engineering with all of you. Whether you're a seasoned developer or just starting your journey in the world of code, this blog is here to empower you and elevate your skills. What to Expect: Expect a diverse range of content, including in-depth tutorials, coding challenges, software development tips, algorithmic insights, tech reviews, and discussions on the latest trends in the tech sphere. We'll explore various programming languages, design patterns, data structures, and best practices to help you become a more proficient engineer.