Sorted Dictionaries and Custom Comparators in C#

Topic Overview

Welcome to our exploration of sorted dictionaries using custom classes and comparers in C#. In today's lesson, we'll learn how to use custom classes as keys in sorted dictionaries. This approach enhances data organization and access. With the addition of comparers, we can dictate the order in such dictionaries.

Quick Recap on Sorted Dictionaries

A sorted dictionary is a dictionary with its keys always in order. This arrangement makes operations like searching for keys within a range more efficient. In C#, we use the SortedDictionary class to create them:

using System;
using System.Collections.Generic;

public class Program {
    public static void Main(string[] args) {
        SortedDictionary<string, int> sMap = new SortedDictionary<string, int>();
        sMap["a"] = 1;
        sMap["b"] = 2;
        sMap["c"] = 3;
        
        foreach(var kvp in sMap) {
            Console.WriteLine($"{kvp.Key}={kvp.Value}");  // Outputs "a=1", "b=2", "c=3"
        }
    }
}

Introduction to Custom Classes in C#

Custom classes enable us to create objects that fit our data — for instance, a Person class for employee information or a Book class for a library database. In C#, classes are the blueprints for creating objects.

Consider this simple class, for example:

using System;

public class Person {
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age) {
        Name = name;
        Age = age;
    }
}

public class Program {
    public static void Main(string[] args) {
        Person person = new Person("John Doe", 30);
        Console.WriteLine(person.Name);  // Outputs "John Doe"
        Console.WriteLine(person.Age);   // Outputs 30
    }
}

Using Custom Classes as Keys in Sorted Dictionaries

Using custom classes as dictionary keys helps organize complex multivariate keys in a sorted dictionary. Consider the following example using the Person class as a key in a sorted dictionary (i.e., SortedDictionary). However, this will not work yet.

using System;
using System.Collections.Generic;

public class Person {
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age) {
        Name = name;
        Age = age;
    }

    public override int GetHashCode() {
        return HashCode.Combine(Name, Age);
    }

    // Rest of the class...
}

public class Program {
    public static void Main(string[] args) {
        SortedDictionary<Person, string> people = new SortedDictionary<Person, string>();

        Person john = new Person("John", 30);
        Person alice = new Person("Alice", 25);

        people[john] = "Programmer";
        people[alice] = "Designer";
    }
}

We can see here that John is assigned the value "Programmer", and Alice is assigned the value "Designer." However, this code will produce an exception. The reason is that the SortedDictionary needs a way to compare the Person objects to maintain its order. This requires not only implementing GetHashCode and Equals (important for identifying objects) but also providing a means to compare objects, typically through the IComparable<T> interface or a custom IComparer<T>.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal