Home > Software engineering >  How to make one Comparer call another one?
How to make one Comparer call another one?

Time:06-20

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?

CodePudding user response:

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);
    }
}

CodePudding user response:

A different approach to user18387401's is to simply implement the interface for both types:

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