DEV Community

Cover image for C# Collection Types for Beginners
Lou Creemers
Lou Creemers

Posted on

4

C# Collection Types for Beginners

Hi lovely readers,

Collections help you store and manage groups of items, like names in a list or values in a lookup table. Choosing the right collection can save you time, prevent bugs, and make everything way faster. When I got started with coding it was a big challenge for me which collection type I should use to get the best result. So I hope that this blog post will help you to clear some stuff up.

Let’s get started!


1. Why Collections Matter

When you start coding, you often use single variables. But real apps need to handle many items: user inputs, search results, configuration values, and more. Collections let you group these items together so you can:

  • Store many values in one object

  • Iterate through items easily (e.g., with foreach)

  • Search, sort, and filter data

  • Share data between methods and classes

This is backend development 101, so I hope you already know what lists and array do to a certain extend. However, having a solid grasp of collections saves you so much time and speed so be sure you know how all collection types work.


2. Non-Generic vs. Generic Collections

Non-Generic Collections

Older collection types (like ArrayList and Hashtable) store items as object. When you retrieve an item, you must cast it:

var list = new ArrayList();
list.Add("hello");
string s = (string)list[0];  // explicit cast
Enter fullscreen mode Exit fullscreen mode

Drawbacks:

  • Runtime errors if the cast is wrong

  • Boxing/unboxing slows performance

  • Less clear code, since item types are not explicit

Generic Collections

Generics let you specify the item type up front (List<T>, Dictionary<TKey, TValue>, HashSet<T>). For example:

var numbers = new List<int>();
numbers.Add(10);
int x = numbers[0];  // no cast needed
Enter fullscreen mode Exit fullscreen mode

Benefits:

  1. Type safety: Compiler checks item types

  2. Better performance: No boxing/unboxing

  3. Clearer code: You see the type at a glance

Use generics in almost all cases. Only use non-generic collections for legacy code.


3. Main Collection Types in .NET

Arrays

  • What? Fixed-size, zero-based collections of a single type.

  • When? You know the exact number of items.

string[] names = new string[3];
names[0] = "Alice";
names[1] = "Bob";
names[2] = "Carol";

foreach (var name in names)
    Console.WriteLine(name);
Enter fullscreen mode Exit fullscreen mode

Lists (List<T>)

  • What? Resizable arrays—grow or shrink automatically.

  • When? You need dynamic collections.

var list = new List<int> { 1, 2, 3 };
list.Add(4);
list.RemoveAt(0);

foreach (var n in list)
    Console.WriteLine(n);
Enter fullscreen mode Exit fullscreen mode

Dictionaries (Dictionary<TKey, TValue>)

  • What? Fast lookups by key (like a phone book).

  • When? You need to map keys to values.

var phoneBook = new Dictionary<string, string>();
phoneBook["Alice"] = "555-1234";

if (phoneBook.TryGetValue("Bob", out var number))
    Console.WriteLine(number);
Enter fullscreen mode Exit fullscreen mode

Sets (HashSet<T> / SortedSet<T>)

  • What? Unique items: HashSet<T> for unordered, SortedSet<T> for sorted.

  • When? You need to eliminate duplicates.

var set = new HashSet<int> { 1, 2, 2, 3 };  // {1,2,3}
Enter fullscreen mode Exit fullscreen mode

Stacks & Queues

  • Stack (LIFO): Last in, first out.

    var stack = new Stack<string>();
    stack.Push("first");
    stack.Push("second");
    Console.WriteLine(stack.Pop());  // "second"
    
  • Queue (FIFO): First in, first out.

    var queue = new Queue<string>();
    queue.Enqueue("hello");
    queue.Enqueue("world");
    Console.WriteLine(queue.Dequeue());  // "hello"
    

4. Tips (What I’ve learned)

  • Don’t modify in foreach: Changing a collection while iterating throws an error. Instead, use a for loop or iterate over list.ToList().

  • Reserve capacity: For large lists, use new List<T>(capacity) or set list.Capacity to reduce resizing costs.

  • Clear vs. recreate: list.Clear() keeps internal arrays; list = new List<T>() allocates new ones.

  • Bulk additions: Use AddRange to add many items at once.


5. Choosing the Right Collection

  • Fixed-size? Use arrays.

  • Dynamic list? Use List<T>.

  • Key/value pairs? Use Dictionary<TKey, TValue> (or SortedDictionary for ordered keys).

  • Unique items? Use HashSet<T> or SortedSet<T>.

  • Thread-safe? Use ConcurrentQueue<T> or ConcurrentDictionary<TKey, TValue>.


That’s a wrap

Now you know why collections matter, the main types in .NET, and how to avoid common mistakes. Try these collections in your next project, and watch your code become cleaner, faster, and more reliable.

If you have any questions or comments, feel free to reach out (louella.dev/socials) or leave a comment down below.

See ya!

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay