Search code examples
c#icomparer

How to make one Comparer call another one?


Context
I have a list of Movies, which have a Title and a DurationInMinutes:

Movie m1 = new Movie("Jurassic World Dominion", 149);
Movie m2 = new Movie("Top Gun Maverick", 152);
Movie m3 = new Movie("Docter Strange in the Multiverse of Madness", 119);

I also have a list of Screenings for these movies, which consist of a Movie with it's startTime :

DateTime startTime1 = new DateTime(2022, 6, 18, 8, 30, 0);
DateTime startTime2 = new DateTime(2022, 6, 18, 9, 0, 0);
DateTime startTime3 = new DateTime(2022, 6, 18, 14, 0, 0);

Screening s1 = new Screening(m1, startTime1);
Screening s2 = new Screening(m2, startTime1);
Screening s3 = new Screening(m2, startTime2);
Screening s4 = new Screening(m3, startTime3);

To sort the movies based on their duration (from longest to shortest), I use the IComparer<T> interface:

class DurationComparer : IComparer<Movie> {
    public int Compare(Movie x, Movie y) {
        return y.DurationInMinutes.CompareTo(x.DurationInMinutes);
    }
}

Problem
Now I'd like to sort them the same way, but starting from a list of Screenings instead of a list of Movies. I have written this piece of code, which works fine...

class MovieDurationComparer : IComparer<Screening> {
    public int Compare(Screening x, Screening y) {
        return y.Movie.DurationInMinutes.CompareTo(x.Movie.DurationInMinutes);
    }
}

... but I'd like this IComparer to make use of the first one to avoid repeating myself (DRY). For some reason I have no problem doing something similar with a method, but with an interface, I get stuck.

Question
How to call the first IComparer from the second one?


Solution

  • The MovieDurationComparer class can create an instance of the Duration class within it:

    class MovieDurationComparer : IComparer<Screening> {
        private DurationComparer durationComparer = new DurationComparer();
    
        public int Compare(Screening x, Screening y) {
            return durationComparer.Compare(x.Movie, y.Movie);
        }
    }