C# Collections and Generics
What are Collections?
• Collections are used to store, manage, and
manipulate groups of related objects.
• C# supports:
• - Non-generic collections (older, not type-safe)
• - Generic collections (type-safe, flexible)
Non-Generic Collections
• Belong to System.Collections namespace.
• Examples:
• - ArrayList
• - Hashtable
• - Stack
• - Queue
ArrayList
• ArrayList list = new ArrayList();
• list.Add(1);
• list.Add("Hello"); // Allows mixed types
• Pros: Easy to use
• Cons: Not type-safe; boxing/unboxing needed
Hashtable
• Hashtable ht = new Hashtable();
• ht["id"] = 101;
• ht["name"] = "Alice";
• Stores key-value pairs with unique keys.
• No compile-time type checking.
Stack and Queue
• Stack s = new Stack();
• s.Push(10);
• s.Pop();
• Queue q = new Queue();
• q.Enqueue(10);
• q.Dequeue();
Why Use Generics?
• Benefits of Generics:
• - Type safety
• - Better performance (no boxing/unboxing)
• - Code reusability
Generic Collections
• Namespace: System.Collections.Generic
• Examples:
• - List<T>
• - Dictionary<TKey, TValue>
• - HashSet<T>
• - Queue<T>, Stack<T>
• - LinkedList<T>
List<T>
• List<string> names = new List<string>();
• names.Add("Alice");
• names.Add("Bob");
• Dynamic resizing, index-based access, type-
safe.
Dictionary<TKey, TValue>
• Dictionary<int, string> dict = new
Dictionary<int, string>();
• dict.Add(1, "Apple");
• dict.Add(2, "Banana");
• Fast lookup by key. Keys must be unique.
HashSet<T>
• HashSet<int> numbers = new HashSet<int>();
• numbers.Add(1);
• numbers.Add(2);
• numbers.Add(1); // Ignored, no duplicates
Queue<T> and Stack<T>
• Queue<string> q = new Queue<string>();
• q.Enqueue("first");
• q.Dequeue();
• Stack<string> s = new Stack<string>();
• s.Push("last");
• s.Pop();
LinkedList<T>
• LinkedList<int> list = new LinkedList<int>();
• list.AddLast(10);
• list.AddFirst(5);
• Doubly linked list. Fast insert/delete at both
ends.
IEnumerable & IEnumerator
• IEnumerable: Interface for iteration
• IEnumerator: MoveNext(), Current, Reset()
• foreach (var item in list)
{ Console.WriteLine(item); }
Custom Generics
• public class MyGeneric<T>
• {
• public T Value;
• }
Best Practices
• - Use List<T> over ArrayList
• - Prefer Dictionary<TKey, TValue> for key-value
• - Avoid boxing by using generics
• - Use HashSet<T> when no duplicates needed