Dictionaries are a cornerstone of efficient data management in C#. They allow you to store and retrieve key-value pairs quickly and intuitively. When combined with the dynamic capabilities of Excel for data storage, they become even more powerful. In this article, we’ll explore dictionaries in depth, how they work, and how to use them in real-world applications. Building on our previous articles, we’ll integrate dictionaries with an Excel file to create a robust, interactive country lookup tool.
What is a Dictionary in C#?
A Dictionary<TKey, TValue>
in C# is a highly efficient collection that organizes data as key-value pairs. This design allows for quick retrieval of values using unique keys. Unlike arrays or lists, which rely on numeric indices, dictionaries provide flexibility by letting you use any data type as a key.
Components of a Dictionary
-
Key (
TKey
):- The unique identifier for each value.
- Example:
"NOR"
(country code for Norway).
-
Value (
TValue
):- The data associated with the key.
- Example:
"Norway, Europe, Population: 5,379,475"
.
Advantages of Using a Dictionary
1. Fast Lookups
Dictionaries use a hash-based storage mechanism, making lookups almost instantaneous, even for large collections.
var countryDictionary = new Dictionary<string, string>
{
{ "NOR", "Norway" },
{ "FIN", "Finland" }
};
// Retrieve Norway
string country = countryDictionary["NOR"];
Console.WriteLine(country); // Output: Norway
2. Flexible Key Management
Keys can be of any type (string
, int
, Guid
, etc.), making dictionaries adaptable for various applications.
var personDictionary = new Dictionary<Guid, string>();
Guid id = Guid.NewGuid();
personDictionary.Add(id, "John Doe");
Console.WriteLine(personDictionary[id]); // Output: John Doe
3. Dynamic Sizing
Unlike arrays, dictionaries don’t require a fixed size. They grow dynamically as you add more key-value pairs.
4. Ensuring Uniqueness
Keys in a dictionary must be unique, preventing accidental overwrites and ensuring data integrity.
How Dictionaries Work Under the Hood
-
Hashing:
- Each key is hashed to generate a unique hash code.
- The hash code determines where the value is stored.
-
Collisions:
- When two keys produce the same hash code, the dictionary resolves conflicts using chaining or open addressing.
-
Efficiency:
- Lookups, additions, and deletions take constant time on average, even for large collections.
Building an Application: Country Lookup Using Dictionaries
In our previous articles, we created an Excel-based data management system using an ExcelReaderWriter
class. We’ll now enhance this by using dictionaries for efficient lookups.
Step 1: Setting Up the Excel File
The Excel file, Countries.xlsx
, should have the following structure:
-
Sheet Name:
Countries
-
Columns:
-
Name
: Name of the country. -
Code
: Three-letter country code. -
Region
: Geographic region. -
Population
: Population of the country.
-
Step 2: Extending the ExcelReaderWriter Class
The ExcelReaderWriter
class will include a method to populate a dictionary with data from the Excel file.
using OfficeOpenXml;
using System.Collections.Generic;
using System.IO;
public class ExcelReaderWriter
{
private readonly string _filePath;
public ExcelReaderWriter(string filePath)
{
_filePath = filePath;
}
// Method to read country data into a dictionary
public Dictionary<string, Country> ReadAllCountriesIntoDictionary()
{
var countries = new Dictionary<string, Country>();
using (var package = new ExcelPackage(new FileInfo(_filePath)))
{
var worksheet = package.Workbook.Worksheets["Countries"];
int row = 2; // Data starts from the second row
while (worksheet.Cells[row, 1].Value != null)
{
var name = worksheet.Cells[row, 1].Value?.ToString();
var code = worksheet.Cells[row, 2].Value?.ToString();
var region = worksheet.Cells[row, 3].Value?.ToString();
var population = int.Parse(worksheet.Cells[row, 4].Value?.ToString() ?? "0");
var country = new Country(name, code, region, population);
countries[code] = country; // Use the country code as the key
row++;
}
}
return countries;
}
}
Step 3: The Country Class
The Country
class models the data for each country.
public class Country
{
public string Name { get; }
public string Code { get; }
public string Region { get; }
public int Population { get; }
public Country(string name, string code, string region, int population)
{
Name = name;
Code = code;
Region = region;
Population = population;
}
}
Step 4: Formatting Populations
To improve readability, we’ll format population numbers with commas.
public static class PopulationFormatter
{
public static string FormatPopulation(int population)
{
return population > 0 ? population.ToString("N0") : "Unknown";
}
}
Step 5: Building the Interactive Application
The program will allow users to look up countries by their three-letter codes.
using System;
class Program
{
static void Main(string[] args)
{
string filePath = "Countries.xlsx";
var excelHandler = new ExcelReaderWriter(filePath);
Console.WriteLine("Reading all countries into a dictionary...");
var countryDictionary = excelHandler.ReadAllCountriesIntoDictionary();
while (true)
{
Console.WriteLine("\nEnter a three-letter country code (or type 'exit' to quit):");
string inputCode = Console.ReadLine()?.ToUpper();
if (inputCode == "EXIT")
break;
if (countryDictionary.TryGetValue(inputCode, out var country))
{
Console.WriteLine($"\nCountry Details:");
Console.WriteLine($"Name: {country.Name}");
Console.WriteLine($"Region: {country.Region}");
Console.WriteLine($"Population: {PopulationFormatter.FormatPopulation(country.Population)}");
}
else
{
Console.WriteLine("\nCountry not found.");
}
}
}
}
Expected Output
Case 1: Valid Key
Enter a three-letter country code (or type 'exit' to quit):
NOR
Country Details:
Name: Norway
Region: Europe
Population: 5,379,475
Case 2: Invalid Key
Enter a three-letter country code (or type 'exit' to quit):
XYZ
Country not found.
Case 3: Exit Program
Enter a three-letter country code (or type 'exit' to quit):
EXIT
Conclusion
This article combined our earlier Excel data handling techniques with the power of dictionaries in C#. By integrating these two technologies, we’ve built a dynamic, efficient, and scalable application for country lookups. This approach is ideal for applications that require fast lookups, meaningful keys, and dynamic data management.
Expand this application by adding features like filtering countries by region, exporting results to Excel, or validating user input for stricter error handling. Happy coding!
Top comments (0)