Sorting in C#

Sorting a list of simple and complex types in C#.

In the previous two articles of this series, we discussed:

  1. Dictionary in C#
  2. List in C#

Before going any further let's first understand what simple types are in C#.

    Int, float, double, string and so on are simple types.

Let's look at an example of a simple type.

Example 1: Sorting a list of type float.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4.   
  5. namespace SortingSimpleType {  
  6.     class Program {  
  7.         static void Main(string[] args) {  
  8.             //list collection of float  
  9.             List<float> floatList = new List<float>() { 123.2f, 33.2f, 82f, 55.5f, 190.45f };  
  10.             //loop through each floatList items  
  11.             foreach(float f in floatList) {  
  12.                 Console.WriteLine(f);  
  13.             }  
  14.         }  
  15.     }  
  16. }  
Run the application.

Run

To sort a list collection, we can use the Sort method.
  1. //to sort a list, use sort method  
  2. floatList.Sort();  
  3. Console.WriteLine();  
  4. Console.WriteLine("Result after sorting");  
  5. foreach(float i in floatList) {  
  6.     Console.WriteLine(i);  
  7. }  
This is how the entire cs file looks.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4.   
  5. namespace SortingSimpleType {  
  6.     class Program {  
  7.         static void Main(string[] args) {  
  8.             List<float> floatList = new List<float>() { 123.2f, 33.2f, 82f, 55.5f, 190.45f };  
  9.             Console.WriteLine("Result before sorting");  
  10.             foreach(float f in floatList) {  
  11.                 Console.WriteLine(f);  
  12.             }  
  13.             floatList.Sort();  
  14.             Console.WriteLine();  
  15.             Console.WriteLine("Result after sorting");  
  16.             foreach(float i in floatList) {  
  17.                 Console.WriteLine(i);  
  18.             }  
  19.         }  
  20.     }  
  21. }  
Run the application.

application

Example 2: Sorting a list of type string.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4.   
  5. namespace SortingSimpleTypeTwo {  
  6.     class Program {  
  7.         static void Main(string[] args) {  
  8.             //create a list of string  
  9.             List<string> stringList = new List<string>() { "Michael""Aiden""Sara""James""Sam""Max" };  
  10.             //output before sorting  
  11.             Console.WriteLine("Result before sorting");  
  12.             //loop through each stringList items  
  13.             foreach(string s in stringList) {  
  14.                 Console.WriteLine(s);  
  15.             }  
  16.             //sorting  
  17.             stringList.Sort();  
  18.             Console.WriteLine();  
  19.             //output after sorting  
  20.             Console.WriteLine("Result after sorting");  
  21.             foreach(string s in stringList) {  
  22.                 Console.WriteLine(s);  
  23.             }  
  24.   
  25.         }  
  26.     }  
  27. }  
Run the application.

Run the application

Example 3: Sorting a list of complex type.

Complex types are classes like Employee, Student, Customer, Sales and so on.

In the previous two examples we saw how to sort a list of simple types. Now let's see how to sort a list of complex types.
  1. using System.Collections.Generic;  
  2.   
  3. namespace SortingComplexType {  
  4.     //create a class Student  
  5.     class Student {  
  6.         //add four uto-implmeneted properties  
  7.         public int StudentId { getset; }  
  8.         public string Name { getset; }  
  9.         public string Gender { getset; }  
  10.         public double TotalMarks { getset; }  
  11.     }  
  12.     class Program {  
  13.         static void Main(string[] args) {  
  14.             //create five objects of Student class and assign values for the properties  
  15.             Student sOne = new Student() {  
  16.                 StudentId = 104,  
  17.                 Name = "Lara Croft",  
  18.                 Gender = "Female",  
  19.                 TotalMarks = 450.55  
  20.             };  
  21.   
  22.             Student sTwo = new Student() {  
  23.                 StudentId = 102,  
  24.                 Name = "Sam Fisher",  
  25.                 Gender = "Male",  
  26.                 TotalMarks = 341  
  27.             };  
  28.   
  29.             Student sThree = new Student() {  
  30.                 StudentId = 101,  
  31.                 Name = "Aiden Pearce",  
  32.                 Gender = "Male",  
  33.                 TotalMarks = 750.32  
  34.             };  
  35.   
  36.             Student sFour = new Student() {  
  37.                 StudentId = 103,  
  38.                 Name = "Michael",  
  39.                 Gender = "Male",  
  40.                 TotalMarks = 612  
  41.             };  
  42.   
  43.             Student sFive = new Student() {  
  44.                 StudentId = 105,  
  45.                 Name = "Black Widow",  
  46.                 Gender = "Female",  
  47.                 TotalMarks = 464  
  48.             };  
  49.   
  50.             //create a new List object of type Student which is a complex type  
  51.             List<Student> StudentList = new List<Student>();  
  52.             //add all the student objects in this StudentList  
  53.             StudentList.Add(sOne);  
  54.             StudentList.Add(sTwo);  
  55.             StudentList.Add(sThree);  
  56.             StudentList.Add(sFour);  
  57.             StudentList.Add(sFive);  
  58.   
  59.             System.Console.WriteLine("Result before sorting");  
  60.             //to retrieve all the details of all the students, use foreach loop  
  61.             foreach(Student s in StudentList) {  
  62.                 System.Console.WriteLine("Id  " + "->" + s.StudentId + " " + "Name  " + "->" + " " + s.Name + "  Gender  " + "->" + "  " + s.Gender + "  " + "  Total Marks  " + "->" + s.TotalMarks);  
  63.             }  
  64.         }  
  65.     }  
  66. }  
Run the application.

output

That is the data before sorting. Now let's sort this complex list item.

Add the following code just after the previous foreach loop:
  1. StudentList.Sort();  
  2. System.Console.WriteLine();  
  3. System.Console.WriteLine("Result after sorting");  
  4. foreach(Student s in StudentList) {  
  5.     System.Console.WriteLine("Id  " + "->" + s.StudentId + " " + "Name  " + "->" + " " + s.Name + "  Gender  " + "->" + "  " + s.Gender + "  " + "  Total Marks  " + "->" + s.TotalMarks);  
  6. }  
Run the application.

results

We get the results before sorting but we got an exception after sorting. So, what is the cause of this exception?

The .NET runtime does not know how to sort complex types. It is our job to tell .NET how to sort the data and for that we need to implement an interface called IComparable.

But now you might be thinking, we haven't implemented the IComparable interface when we were sorting a simple type. So, why did we not get an exception there?

Because a simple type such as float, string and int already implements the IComparable interface.

Right-click on the string class and go to definition, you will seethat the String class implements the IComparable interface.

IComparable

To sort a list of complex types, the complex type must implement the IComparable interface and provide the implementation for the CompareTo method.

CompareTo

The following is the implementation of the IComparable interface.
  1. public class Student: IComparable<Student> {  
  2.         public int StudentId { getset; }  
  3.         public string Name { getset; }  
  4.         public string Gender { getset; }  
  5.         public double TotalMarks { getset; }  
  6.   
  7.         public int CompareTo(Student s) {  
  8.             if(this.StudentId > s.StudentId) {  
  9.                 return 1;//meaning this object is greater than other object  
  10.             }  
  11.             else if(this.StudentId < s.StudentId) {  
  12.                 return -1; //meaning this object is smaller than other object  
  13.             }  
  14.             else {  
  15.                 return 0; // both are equal  
  16.             }  
  17.         }  
  18.     }  

 

  1. IComparable<type> the type should be IComparable<Student>.

  2. Change the type object to Student in the parameter of the CompareTo method and compare the current object (this) with the object s.

Run the application.

CompareTo method

So we get the result as expected. All the results are sorted by StudentId.

Now, here in our project we own this Student class. So, we can change it the way we need it.

  1. public class Student{  
  2.         //add four auto-implemented properties  
  3.         public int StudentId { getset; }  
  4.         public string Name { getset; }  
  5.         public string Gender { getset; }  
  6.         public double TotalMarks { getset; }  
  7. }  
But in reality, there are several ways in which you do not own a class's code but you want to change the default sort functionality provided by the class.

For that we need to implement IComparer.

How to implement

First we need to create a new class and inherit that class from IComparer<T>, the type here should be the type of object that we want to compare from.
  1. class SortingClass: IComparer<Student> {  
  2.     public int Compare(Student x, Student y) {  
  3.         //  
  4.     }  
Let's say this time we want to sort the list by name.
  1. class SortingClass: IComparer<Student> {  
  2.     public int Compare(Student x, Student y) {  
  3.         if(x.Name.Length > y.Name.Length) {  
  4.             return 1;  
  5.         }  
  6.         else if(x.Name.Length < y.Name.Length) {  
  7.             return -1;  
  8.         }  
  9.         else {  
  10.             return 0;  
  11.         }  
  12.     }  
In the preceding we have created a new class “SortingClass” that inherits from an interface IComparer and the type of this interface is Student.

This IComparer interface has a method Compare that we need to implement and this method has two parameters of the type we specified in IComparer. Now all we need to do is compare Student x with Student object y.

After implementation, create a new instance of this SortingClass and pass the object in the third overloaded version of the Sort method as a parameter argument.

Sort method
  1. SortingClass sc = new SortingClass();  
  2. StudentList.Sort(sc);  
Run the application.

interface

This time, the list is sorted by Name even after providing a default sort functionality in the Student class.

code

So, whenever you don't own a class and want to override the default sort functionality and want to provide your own then implement the IComparer interface.

I hope you like. Thank you.