C#’s strong collection types enable developers to store, organize, and manipulate data, crucial for real-world applications like HR systems, payroll solutions, or project management tools. This article walks through the most essential built-in collections, explaining their use cases, code syntax, and practical scenarios for beginners through senior engineers.
1. C# Arrays
Arrays are fixed-size, strongly typed collections used for storing simple, indexed lists of elements.
Example: Employee Array
public class Employee
{
public int Id {
get;
set;
}
public string Name {
get;
set;
}
}
// Declare and initialize
Employee[] employees = new Employee[3];
employees[0] = new Employee {
Id = 1, Name = "Kiran"
};
employees[1] = new Employee {
Id = 2, Name = "Kumar"
};
employees[2] = new Employee {
Id = 3, Name = "Mark"
};
// Access by index
Console.WriteLine(employees[1].Name); // Output: Kiran
// Iteration
foreach(var emp in employees)
Console.WriteLine($"{emp.Id}: {emp.Name}");
Key points
- Fixed size; cannot dynamically add/remove items after creation.
- Fast access via index.
- Use when the number of employees is known and unchanging.
2. Non-Generic Collections
ArrayList
- Stores objects (any type), resizes dynamically, but is not type-safe.
- Now largely obsolete—prefer generics.
using System.Collections;
ArrayList staff = new ArrayList();
staff.Add("Kiran"); // string
staff.Add(100); // int
staff.Add(new Employee {
Id = 1, Name = "Kumar"
}); // Employee object
foreach(var s in staff)
Console.WriteLine(s); // May cause runtime errors if type is unexpected!
Drawbacks: No compile-time type checking; risk of invalid casts.
3. Generic Collections
Use these for all new code. Part of System.Collections.Generic.
List<T>
Resizable, type-safe, index-accessed collection.
List < Employee > employeeList = new List < Employee >
{
new Employee {
Id = 5, Name = "Derek"
},
new Employee {
Id = 6, Name = "Kiran"
}
};
employeeList.Add(new Employee {
Id = 7, Name = "Mark"
});
foreach(var e in employeeList)
Console.WriteLine($"{e.Id}: {e.Name}");
Dictionary < TKey, TValue >
Dictionary<TKey, TValue>
Key-value pairs for lookups, e.g., by Employee ID.
Dictionary < int, Employee > directory = new Dictionary < int, Employee > ();
directory[101] = new Employee {
Id = 101, Name = "Kiran"
};
directory.Add(102, new Employee {
Id = 102, Name = "Kumar"
});
if (directory.ContainsKey(101))
Console.WriteLine(directory[101].Name); // Output: Kiran
Queue<T>
First-In-First-Out (FIFO) collection. Use for ordered tasks like employee service requests.
Queue < string > helpDesk = new Queue < string > ();
helpDesk.Enqueue("Reset Credentails for Kiran");
helpDesk.Enqueue("Setup email for Kumar");
// Process tasks
while (helpDesk.Count > 0)
Console.WriteLine("Processing: " + helpDesk.Dequeue());
Stack<T>
Last-In-First-Out (LIFO). Good for undo/redo operations or backtracking user changes.
Stack < string > employeeUndo = new Stack < string > ();
employeeUndo.Push("Added Kiran");
employeeUndo.Push("Edited Kumar");
Console.WriteLine(employeeUndo.Pop()); // Output: Edited Kumar
Join the conversation! Your thoughts help the community grow.