IComparable vs IComparer
Tags: csharp
Published: 2020-10-02 08:59:03

## **Introduction**
When doing sorting in C#, you will come across with the interface IComparable and IComparer.
<br>
Both of the interfaces are frequently used together, and people often got confused because of its similar name, even though they serve different purposes.
<br>
On this article, I will explain the difference between both of the IComparable and IComparer.
***

First, let us dive into the concept of sorting.
<br>
Assume that we have a list of integer that we want to sort in an ascending order. 
<br>
Since we are using the data type **Int** and the built in **List**, we can use the provided **Sort** method by Microsoft.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lxwhpwtfyy45alwpd8dg.PNG)

Which will result to a sorted list: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/78ie52z8hwb17d31hfmt.PNG)

This works because the Sort method knows what it has to sort, which in this case is an Integer number.
<br>

But, what if I want to sort a list that contains user-defined class?
<br>
Let's create a new class called Student, which will contain a name and age of a student.

Note: The age will be a random integer number between 17 to 50.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sua74ndd9uqma1qh9q5v.PNG)

Now let's create 6 students and put them into a list of students.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0cjpiz9ako2d9skfsmwv.PNG)

Then let's print out the list and sort it by their Age using the built in Sort function.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5zdq7msy6mdwobva9z1q.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8e4r48c96gl1dv51ve2u.PNG)
We were able to print it, but what's that?
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ctczovdmfqtxcyw0u56t.PNG)

We got an error! "*At least one object must implement IComparable*"

This happens because the sorting algorithm doesn't know how to sort the elements. Which in this case is the Name of the student's class. 
<br>


## **IComparable**

To be able to sort it, we will have to implement the IComparable interface into our Student class.
<br>
So let's start by implementing it to our class.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1zzraerpchdhn15fmyai.PNG)

Now because we implemented the interface, we will have to implement its method as well. 

Here we will be overriding the CompareTo method.
<br>
The CompareTo method is used to compare one object with another object of the same type. It will then return an integer that indicates the position of the object in the sort order (precedes, follows, occurs)
<br>
If the current value is bigger than the next value it will return 1, else it will return -1. And if both of the value are the same it will return 0. It works like this:
- 1: Swap
- 0: Keep
- -1: Don't swap

<br>
For example, let's say that we have a List of [6,2,10,7,3].

Then we call the CompareTo method on the list, and it will compare the current item **6** with the next item **2**.

Since 6 is bigger than 2, it will return the value 1. So both of the element will swap.

The list is now [2,6,10,7,3] and it will repeat the process again until it becomes [2,3,6,7,10].
<br>
Now let's fill in the CompareTo method:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8bw4wvazrj9buhpaejht.PNG)

What this does is that, it will compare the current Student age with the next Student age.

Let's try running the code and see what happens
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1xk8bdrsduwnxqi1y2me.PNG)

It works! now the students are sorted beautifully based on their age.

We can also sort it by other data by modifying the CompareTo method. Let's try sorting it by their names now:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g0hgyebmwv5vxk0ld22k.PNG)

Which results in:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/re3iuvmjfm4ofb0f3xna.PNG)
All sorted by their names cleanly!
<br>

## **IComparer**

Now after understanding how IComparable works, we can go into how IComparer works.

IComparable allows you to sort on a user-defined class that you have full control in. But, what if you want to apply the sorting in a class you don't have control? Which means you can't change the implementation of the class.
<br>
For example, let's say that we don't have access to modify the student class
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4imsv8qvg2lyaklmfqqr.PNG)

Right now, if we call the sort method, it will sort the student by their names.

Let's say that we want to sort it by their ages. But since we can't modify the Student class, we won't be able to modify the CompareTo method.

This is where IComparer comes in. We will have to create a new class that implements the IComparer interface.
<br>

Let's start by creating a new class then implement the IComparer interface.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2vfxvncxu8vjvbwnys8g.PNG)

Once we created the new class, we will need to implement its method called Compare.

The Compare method is used to perform a comparison between two objects with the same type. It will then return a value which will indicate if one object is less than, equal to, or greater than the other object.
<br
This is what it means by the returned value:
- Less than zero: x is less than y
- Zero: x equals y
- Greater than zero: x is greater than y

<br>
For example, let's say that we are comparing between two object 9 and 3.

When we are comparing it based on x - y, we will compare if 9 is bigger than 3, and since 9 is bigger than 3 it will return 1. 



<br>
Let's fill in the Compare method now:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6by44c28bmk7ofg3wyvi.PNG)

What this is saying is that we will compare the first student's age by the second student's age.

Then we will have to implement our new StudentComparer class into our sorting method by passing it as parameter:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/voi917jzv7yzybn0if57.PNG)

Now let's print out the result:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ccyvbq7bpd7iv2ocknx0.PNG)

Nice it's sorted by the student age!
<br>
It is sorted in an ascending order. But, what if we want to sort it in a descending order? 

The Compare method can be modified to sort the objects to our liking. In this case its sorted in an ascending order because we are comparing it by x - y. 

If we want to sort it in a descending order we will have to flip it into y - x.
<br>
Let's use an example to understand the positioning of x - y.

Assume that we want to sort a list of [8,5,9,7] in an ascending and descending order.
<br>
When we want to sort in ascending order it will be x - y. This is because when we take the first object 8 (x) and the second object 5 (y), we will compare them and since 8 is bigger it will return 1, which means that it will be swapped (Refer to IComparable rule above).

Now the list will be [5, 8, 9, 7]. Then we will keep comparing the object with the next object until the list becomes [5,7,8,9].

<br>
Now when we want to sort it in descending order it will be y - x.
<br>
Using the above list, we take the object y which is 5 and object x which is 8. Here we compare them and 5 is less than 8 so we will not swap them. 

The list will stay as [8,5,9,7]. Then for the next comparison it will compare between object y which is 9 and object x which is 8.
9 is bigger than 8 so they will swap.

New list is now [9,5,8,7]. This comparison will keep repeating until we get a list of [9,8,7,5].

<br>
Let's try sorting the student age in descending order:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wo82ocozjhsxo6i6iuqj.PNG)

Printing out the result:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3lmccxgygaz1h9k9ov7i.PNG)

Great! It is now sorted in an descending order.
<br>

## **Summary**

So that's how both IComparable and IComparer interface works.

I hope you are able to understand how they are different from each other, and how to use them.
<br>
Thank you and have a nice day!