BuildQuill
C# learning path
12 of 25
Lesson 12 of 25
Lesson 12Beginner18 min

C# Dictionaries and Sets

Look up values by meaningful keys, track unique membership, and choose between ordered sequences, mappings, and sets.

Before this lesson

  • Arrays and List<T>
  • Loops
  • Try-style APIs

Add, update, and safely retrieve dictionary entries

Use a set for uniqueness and membership

Select a collection from the questions the program asks most often

The short answer

Dictionary<TKey,TValue> maps each unique key to a value for efficient lookup. HashSet<T> stores unique values and answers membership questions. Use List<T> when order and duplicates are the main concern.

01

Sometimes a position is the wrong identity

A list can answer ‘what is item 3?’ but a stock system usually asks ‘how many notebooks are available?’ Scanning every product each time is indirect. A dictionary attaches a meaningful unique key to each value so the lookup states the real question.

TKey and TValue are generic type parameters. Dictionary<string, int> uses text keys and integer values. Keys must be unique; assigning through the indexer updates the value for an existing key, while Add rejects a duplicate key.

02

Retrieve uncertain keys without an exception

Reading prices["marker"] throws KeyNotFoundException when marker is absent. That is fine only when absence proves a broken internal assumption. When a user or file supplies the key, absence is normal and should be a branch.

TryGetValue performs one lookup and returns both a success flag and the value. ContainsKey followed by the indexer can work but performs the search twice. Choose the API that models the operation directly.

C#
Dictionary<string, decimal> prices = new Dictionary<string, decimal>();
prices["tea"] = 2.50m;
prices["coffee"] = 3.25m;

decimal price;
if (prices.TryGetValue("juice", out price))
{
  Console.WriteLine(price);
}
else
{
  Console.WriteLine("Price not found");
}

Expected output

Price not found
03

A set answers whether a value belongs

HashSet<T> stores each equal value at most once. Add returns false when the value was already present. Sets suit tags, visited identifiers, blocked codes, and removing duplicates when original order is not the primary requirement.

Set operations express larger questions: UnionWith adds values from another set, IntersectWith keeps shared values, and ExceptWith removes values found in another set. These operations can be clearer than nested loops when the domain really is membership.

C#
using System;
using System.Collections.Generic;

class Program
{
  static void Main()
  {
      HashSet<string> attendees = new HashSet<string>();

      Console.WriteLine(attendees.Add("Amina"));
      Console.WriteLine(attendees.Add("Bilal"));
      Console.WriteLine(attendees.Add("Amina"));
      Console.WriteLine(attendees.Count);
  }
}

Expected output

True
True
False
2
04

Choose by the dominant operation

A List is an ordered sequence and allows duplicates. A Dictionary maps unique keys to values. A HashSet represents unique membership. The same data can be forced into any of them, but the wrong choice makes the main operation slow or unclear.

Default string equality is case-sensitive. If product codes or usernames should ignore case, provide an appropriate comparer such as StringComparer.OrdinalIgnoreCase when constructing the dictionary or set. Choosing comparison rules at construction keeps every operation consistent.

QuestionCollectionExample
What is at this position?List<T> or arrayDaily temperatures
What value belongs to this key?Dictionary<TKey,TValue>Price by product code
Have I seen this value?HashSet<T>Processed order IDs
Can duplicates appear in order?List<T>Page visit history

Good habits

  • Use stable, meaningful keys; mutable objects make dangerous dictionary keys.
  • Do not depend on hash collection ordering unless the documented type contract guarantees what you need.
  • Choose an equality comparer that matches the domain at collection creation.

Quick knowledge check

Answer before you reveal.

01Can a Dictionary contain the same key twice?

No. Each key is unique, though multiple keys may map to equal values.

02Why use TryGetValue instead of ContainsKey followed by the indexer?

It retrieves the value and reports absence with one lookup and one clear operation.

Practice challenge

Now build it without copying.

Count votes from a string array using Dictionary<string, int>. Treat candidate names case-insensitively, print each total, and use a HashSet to report the number of unique candidates.

You are done when

  • Repeated names increase an existing count
  • Different capitalization does not create another candidate
  • Missing keys are handled before incrementing

Stretch: Track and print the leading candidate, and state how you handle a tie.

Open challenge in playground

Lesson checkpoint

One small step locks it in

Mark this lesson complete, then keep the momentum going.

Complete and continue

Clear up the details

Frequently asked questions

Are dictionary lookups always constant time?

Hash-based lookup is constant-time on average with suitable hashing, not an absolute guarantee for every input and operation.

How do I keep dictionary entries sorted?

Use an ordered or sorted collection when sorted keys are a real requirement, or sort entries for presentation. Dictionary itself should not be selected for a display-order promise.

Can a set store objects?

Yes, but uniqueness depends on equality and hash-code behavior. Records or types with well-designed equality are often better set elements than mutable identity objects.