Learning C#
C# offers a variety of data structures that can be broadly categorized into primitive types, collections, and more specialized data structures. Here is an overview of some commonly used data structures in C#:
Primitive Types
int, long, float, double, char, bool, etc.
- These are the basic building blocks for data manipulation in C#.
Collections
Arrays
Single-dimensional arrays:
int[] array = new int[10];
Multi-dimensional arrays:
int[,] matrix = new int[3, 3];
Jagged arrays:
int[][] jaggedArray = new int[3][];
Collections from System.Collections Namespace
ArrayList: A non-generic collection of objects.
using System; using System.Collections; class Program { static void Main() { // Create an ArrayList ArrayList arrayList = new ArrayList(); // Add elements to the ArrayList arrayList.Add(1); // Adding an integer arrayList.Add("Hello"); // Adding a string arrayList.Add(3.14); // Adding a double arrayList.Add(DateTime.Now); // Adding a DateTime object // Accessing elements in the ArrayList Console.WriteLine("First element: " + arrayList[0]); // Output: First element: 1 Console.WriteLine("Second element: " + arrayList[1]); // Output: Second element: Hello Console.WriteLine("Third element: " + arrayList[2]); // Output: Third element: 3.14 Console.WriteLine("Fourth element: " + arrayList[3]); // Output: Fourth element: Current DateTime // Modify an element in the ArrayList arrayList[1] = "World"; Console.WriteLine("Modified second element: " + arrayList[1]); // Output: Modified second element: World // Iterate through the ArrayList Console.WriteLine("\nIterating through the ArrayList:"); foreach (var item in arrayList) { Console.WriteLine(item); } // Remove an element from the ArrayList arrayList.Remove(3.14); // Remove the element with value 3.14 Console.WriteLine("\nArrayList after removing 3.14:"); foreach (var item in arrayList) { Console.WriteLine(item); } // Check if an element exists in the ArrayList bool containsHello = arrayList.Contains("Hello"); bool containsWorld = arrayList.Contains("World"); Console.WriteLine("\nContains 'Hello': " + containsHello); // Output: Contains 'Hello': False Console.WriteLine("Contains 'World': " + containsWorld); // Output: Contains 'World': True // Clear the ArrayList arrayList.Clear(); Console.WriteLine("\nArrayList after clearing all elements. Count: " + arrayList.Count); // Output: ArrayList after clearing all elements. Count: 0 } }
Hashtable: A collection of key/value pairs, organized based on the hash code of the key.
using System; using System.Collections; class Program { static void Main() { // Create a new Hashtable instance Hashtable hashtable = new Hashtable(); // Adding key/value pairs to the Hashtable hashtable.Add(1, "One"); hashtable.Add(2, "Two"); hashtable.Add(3, "Three"); // Accessing values in the Hashtable using keys Console.WriteLine("Value for key 1: " + hashtable[1]); Console.WriteLine("Value for key 2: " + hashtable[2]); Console.WriteLine("Value for key 3: " + hashtable[3]); // Checking if a key exists if (hashtable.ContainsKey(2)) { Console.WriteLine("Key 2 exists in the hashtable."); } // Checking if a value exists if (hashtable.ContainsValue("Three")) { Console.WriteLine("Value 'Three' exists in the hashtable."); } // Removing a key/value pair hashtable.Remove(2); // Checking the count of elements in the Hashtable Console.WriteLine("Number of elements in hashtable: " + hashtable.Count); // Iterating through the Hashtable foreach (DictionaryEntry entry in hashtable) { Console.WriteLine("Key: " + entry.Key + ", Value: " + entry.Value); } // Trying to access a removed key if (!hashtable.ContainsKey(2)) { Console.WriteLine("Key 2 has been removed from the hashtable."); } } }
Collections from System.Collections.Generic Namespace
List: A dynamic array that can grow as needed.
using System; using System.Collections.Generic; class Program { static void Main() { // Create a new List instance List<int> list = new List<int>(); // Adding elements to the List list.Add(1); list.Add(2); list.Add(3); // Accessing elements in the List using index Console.WriteLine("Element at index 0: " + list[0]); Console.WriteLine("Element at index 1: " + list[1]); Console.WriteLine("Element at index 2: " + list[2]); // Inserting an element at a specific index list.Insert(1, 5); // Inserts 5 at index 1 // Accessing the updated list Console.WriteLine("After inserting 5 at index 1:"); foreach (int item in list) { Console.WriteLine(item); } // Removing elements from the List list.Remove(2); // Removes the first occurrence of 2 list.RemoveAt(0); // Removes the element at index 0 // Checking the count of elements in the List Console.WriteLine("Number of elements in list: " + list.Count); // Iterating through the List Console.WriteLine("Iterating through the list:"); foreach (int item in list) { Console.WriteLine(item); } // Checking if an element exists in the List if (list.Contains(3)) { Console.WriteLine("List contains the number 3."); } // Converting the List to an array int[] array = list.ToArray(); Console.WriteLine("Elements in the array:"); foreach (int item in array) { Console.WriteLine(item); } // Clearing the List list.Clear(); Console.WriteLine("Number of elements in list after clearing: " + list.Count); } }
Dictionary<TKey, TValue>: A collection of key/value pairs.
using System; using System.Collections.Generic; class Program { static void Main() { // Create a new Dictionary instance Dictionary<int, string> dictionary = new Dictionary<int, string>(); // Adding key/value pairs to the Dictionary dictionary.Add(1, "One"); dictionary.Add(2, "Two"); dictionary.Add(3, "Three"); // Accessing values in the Dictionary using keys Console.WriteLine("Value for key 1: " + dictionary[1]); Console.WriteLine("Value for key 2: " + dictionary[2]); Console.WriteLine("Value for key 3: " + dictionary[3]); // Checking if a key exists if (dictionary.ContainsKey(2)) { Console.WriteLine("Key 2 exists in the dictionary."); } // Checking if a value exists if (dictionary.ContainsValue("Three")) { Console.WriteLine("Value 'Three' exists in the dictionary."); } // Removing a key/value pair dictionary.Remove(2); // Checking the count of elements in the Dictionary Console.WriteLine("Number of elements in dictionary: " + dictionary.Count); // Iterating through the Dictionary foreach (KeyValuePair<int, string> entry in dictionary) { Console.WriteLine("Key: " + entry.Key + ", Value: " + entry.Value); } // Trying to access a removed key if (!dictionary.ContainsKey(2)) { Console.WriteLine("Key 2 has been removed from the dictionary."); } // Updating the value for an existing key dictionary[3] = "Three Updated"; Console.WriteLine("Updated value for key 3: " + dictionary[3]); // Adding a new key/value pair using the indexer dictionary[4] = "Four"; Console.WriteLine("Value for key 4: " + dictionary[4]); } }
Dictionary<TKey, TValue> is type-safe, optimized for performance, and does not allow null keys.
Hashtable is a legacy, non-generic collection that allows null keys and requires casting, which can lead to runtime errors.
Queue: Follows FIFO (first-in, first-out). The first element added is the first one to be removed.
Adding index starts from (0,1,2..n), pop means removes always 0
Front means current 0 the index
Stack: Follows LIFO (last-in, first-out). The last element added is the first one to be removed.
Adding index starts from (n, n-1, n-2), pop means removes always nth index( -1 index in python)
Front means current nth index( -1 index in python)
Primary Operations:
Queue:
push()
: Adds an element to the back of the queue.pop()
: Removes the front element of the queue.front()
: Accesses the front element.back()
: Accesses the back element.
Stack:
push()
: Adds an element to the top of the stack.pop()
: Removes the top element of the stack.top()
: Accesses the top element.
Uses
Queue:
Breadth-First Search (BFS): Used in graph and tree traversal algorithms.
Task Scheduling: Managing tasks in a multi-tasking environment.
Buffer Management: Implementing buffers in networking and I/O operations.
Stack:
Depth-First Search (DFS): Used in graph and tree traversal algorithms.
Expression Evaluation: Evaluating mathematical expressions and parsing.
Backtracking Algorithms: Solving puzzles and pathfinding problems.
Function Call Management: Managing function calls and recursion in programming languages.
Queue: A first-in, first-out (FIFO) collection.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a new Queue instance
Queue<string> queue = new Queue<string>();
// Adding elements to the Queue
queue.Enqueue("First");
queue.Enqueue("Second");
queue.Enqueue("Third");
// Displaying the front element
Console.WriteLine("Front element: " + queue.Peek()); // Outputs "First"
// Removing elements from the Queue
string removedElement = queue.Dequeue();
Console.WriteLine("Removed element: " + removedElement); // Outputs "First"
// Displaying the new front element after dequeue
Console.WriteLine("New front element: " + queue.Peek()); // Outputs "Second"
// Checking the count of elements in the Queue
Console.WriteLine("Number of elements in queue: " + queue.Count);
// Iterating through the Queue
Console.WriteLine("Elements in queue:");
foreach (string item in queue)
{
Console.WriteLine(item);
}
// Checking if the Queue contains a specific element
if (queue.Contains("Second"))
{
Console.WriteLine("Queue contains 'Second'");
}
// Clearing the Queue
queue.Clear();
Console.WriteLine("Number of elements in queue after clearing: " + queue.Count);
}
}
Stack: A last-in, first-out (LIFO) collection.
using System; using System.Collections.Generic; class Program { static void Main() { // Create a stack of strings Stack<string> stack = new Stack<string>(); // Push items onto the stack stack.Push("First"); stack.Push("Second"); stack.Push("Third"); // Display all items in the stack Console.WriteLine("Items in the stack:"); foreach (string item in stack) { Console.WriteLine(item); } // Pop items from the stack Console.WriteLine("\nPopping items:"); while (stack.Count > 0) { string poppedItem = stack.Pop(); Console.WriteLine($"Popped: {poppedItem}"); } // Check if the stack is empty if (stack.Count == 0) { Console.WriteLine("\nThe stack is now empty."); } // Push more items stack.Push("Fourth"); stack.Push("Fifth"); // Peek at the top item without popping it string topItem = stack.Peek(); Console.WriteLine($"\nThe item at the top of the stack is: {topItem}"); // Display all items in the stack after peeking Console.WriteLine("\nItems in the stack after peeking:"); foreach (string item in stack) { Console.WriteLine(item); } } }
HashSet: A collection of unique elements.
using System; using System.Collections.Generic; class Program { static void Main() { // Create a new HashSet instance HashSet<int> hashSet = new HashSet<int>(); // Adding elements to the HashSet hashSet.Add(1); hashSet.Add(2); hashSet.Add(3); // Attempting to add duplicate elements bool added = hashSet.Add(2); // This will return false as 2 is already in the set // Checking if elements exist in the HashSet Console.WriteLine("Contains 1: " + hashSet.Contains(1)); // Outputs true Console.WriteLine("Contains 4: " + hashSet.Contains(4)); // Outputs false // Removing an element from the HashSet hashSet.Remove(2); // Checking the count of elements in the HashSet Console.WriteLine("Number of elements in hashSet: " + hashSet.Count); // Iterating through the HashSet Console.WriteLine("Elements in hashSet:"); foreach (int item in hashSet) { Console.WriteLine(item); } // Converting the HashSet to an array int[] array = new int[hashSet.Count]; hashSet.CopyTo(array); Console.WriteLine("Elements in the array:"); foreach (int item in array) { Console.WriteLine(item); } // Clearing the HashSet hashSet.Clear(); Console.WriteLine("Number of elements in hashSet after clearing: " + hashSet.Count); } }
Collections from System.Collections.Concurrent Namespace
ConcurrentDictionary<TKey, TValue>: A thread-safe dictionary.
ConcurrentDictionary<int, string> concurrentDictionary = new ConcurrentDictionary<int, string>();
ConcurrentQueue: A thread-safe FIFO collection.
ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
ConcurrentStack: A thread-safe LIFO collection.
ConcurrentStack<string> concurrentStack = new ConcurrentStack<string>();
BlockingCollection: A thread-safe collection for adding and taking items.
BlockingCollection<string> blockingCollection = new BlockingCollection<string>();
Specialized Data Structures
LinkedList: A doubly linked list.
LinkedList<int> linkedList = new LinkedList<int>();
SortedList<TKey, TValue>: A collection of key/value pairs, sorted by key.
SortedList<int, string> sortedList = new SortedList<int, string>();
SortedDictionary<TKey, TValue>: A dictionary that maintains the order of elements based on the keys.
SortedDictionary<int, string> sortedDictionary = new SortedDictionary<int, string>();
SortedSet: A set that maintains order.
SortedSet<int> sortedSet = new SortedSet<int>();
Immutable Collections
ImmutableList: A list that does not change.
ImmutableList<int> immutableList = ImmutableList.Create<int>();
ImmutableDictionary<TKey, TValue>: A dictionary that does not change.
ImmutableDictionary<int, string> immutableDictionary = ImmutableDictionary.Create<int, string>();
ImmutableQueue: A queue that does not change.
ImmutableQueue<int> immutableQueue = ImmutableQueue.Create<int>();
ImmutableStack: A stack that does not change.
ImmutableStack<int> immutableStack = ImmutableStack.Create<int>();
ImmutableHashSet: A set that does not change.
ImmutableHashSet<int> immutableHashSet = ImmutableHashSet.Create<int>();
These data structures cover a wide range of use cases, from simple collections to more complex and thread-safe structures, providing a robust foundation for data manipulation in C#.