Sorting a list of simple and complex types in C#.
In the previous two articles of this series, we discussed:
- Dictionary in C#
- 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.
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- namespace SortingSimpleType {
- class Program {
- static void Main(string[] args) {
-
- List<float> floatList = new List<float>() { 123.2f, 33.2f, 82f, 55.5f, 190.45f };
-
- foreach(float f in floatList) {
- Console.WriteLine(f);
- }
- }
- }
- }
Run the application.
To sort a list collection, we can use the
Sort method.
-
- floatList.Sort();
- Console.WriteLine();
- Console.WriteLine("Result after sorting");
- foreach(float i in floatList) {
- Console.WriteLine(i);
- }
This is how the entire cs file looks.
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- namespace SortingSimpleType {
- class Program {
- static void Main(string[] args) {
- List<float> floatList = new List<float>() { 123.2f, 33.2f, 82f, 55.5f, 190.45f };
- Console.WriteLine("Result before sorting");
- foreach(float f in floatList) {
- Console.WriteLine(f);
- }
- floatList.Sort();
- Console.WriteLine();
- Console.WriteLine("Result after sorting");
- foreach(float i in floatList) {
- Console.WriteLine(i);
- }
- }
- }
- }
Run the application.
Example 2: Sorting a list of type string.
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- namespace SortingSimpleTypeTwo {
- class Program {
- static void Main(string[] args) {
-
- List<string> stringList = new List<string>() { "Michael", "Aiden", "Sara", "James", "Sam", "Max" };
-
- Console.WriteLine("Result before sorting");
-
- foreach(string s in stringList) {
- Console.WriteLine(s);
- }
-
- stringList.Sort();
- Console.WriteLine();
-
- Console.WriteLine("Result after sorting");
- foreach(string s in stringList) {
- Console.WriteLine(s);
- }
-
- }
- }
- }
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.
- using System.Collections.Generic;
-
- namespace SortingComplexType {
-
- class Student {
-
- public int StudentId { get; set; }
- public string Name { get; set; }
- public string Gender { get; set; }
- public double TotalMarks { get; set; }
- }
- class Program {
- static void Main(string[] args) {
-
- Student sOne = new Student() {
- StudentId = 104,
- Name = "Lara Croft",
- Gender = "Female",
- TotalMarks = 450.55
- };
-
- Student sTwo = new Student() {
- StudentId = 102,
- Name = "Sam Fisher",
- Gender = "Male",
- TotalMarks = 341
- };
-
- Student sThree = new Student() {
- StudentId = 101,
- Name = "Aiden Pearce",
- Gender = "Male",
- TotalMarks = 750.32
- };
-
- Student sFour = new Student() {
- StudentId = 103,
- Name = "Michael",
- Gender = "Male",
- TotalMarks = 612
- };
-
- Student sFive = new Student() {
- StudentId = 105,
- Name = "Black Widow",
- Gender = "Female",
- TotalMarks = 464
- };
-
-
- List<Student> StudentList = new List<Student>();
-
- StudentList.Add(sOne);
- StudentList.Add(sTwo);
- StudentList.Add(sThree);
- StudentList.Add(sFour);
- StudentList.Add(sFive);
-
- System.Console.WriteLine("Result before sorting");
-
- foreach(Student s in StudentList) {
- System.Console.WriteLine("Id " + "->" + s.StudentId + " " + "Name " + "->" + " " + s.Name + " Gender " + "->" + " " + s.Gender + " " + " Total Marks " + "->" + s.TotalMarks);
- }
- }
- }
- }
Run the application.
That is the data before sorting. Now let's sort this complex list item.
Add the following code just after the previous
foreach loop:
- StudentList.Sort();
- System.Console.WriteLine();
- System.Console.WriteLine("Result after sorting");
- foreach(Student s in StudentList) {
- System.Console.WriteLine("Id " + "->" + s.StudentId + " " + "Name " + "->" + " " + s.Name + " Gender " + "->" + " " + s.Gender + " " + " Total Marks " + "->" + s.TotalMarks);
- }
Run the application.
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.
To sort a list of complex types, the complex type must implement the
IComparable interface and provide the implementation for the CompareTo method.
The following is the implementation of the IComparable interface.
- public class Student: IComparable<Student> {
- public int StudentId { get; set; }
- public string Name { get; set; }
- public string Gender { get; set; }
- public double TotalMarks { get; set; }
-
- public int CompareTo(Student s) {
- if(this.StudentId > s.StudentId) {
- return 1;
- }
- else if(this.StudentId < s.StudentId) {
- return -1;
- }
- else {
- return 0;
- }
- }
- }
- IComparable<type> the type should be IComparable<Student>.
- 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.
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.
- public class Student{
-
- public int StudentId { get; set; }
- public string Name { get; set; }
- public string Gender { get; set; }
- public double TotalMarks { get; set; }
- }
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 implementFirst 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.
- class SortingClass: IComparer<Student> {
- public int Compare(Student x, Student y) {
-
- }
Let's say this time we want to sort the list by name.
- class SortingClass: IComparer<Student> {
- public int Compare(Student x, Student y) {
- if(x.Name.Length > y.Name.Length) {
- return 1;
- }
- else if(x.Name.Length < y.Name.Length) {
- return -1;
- }
- else {
- return 0;
- }
- }
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.
- SortingClass sc = new SortingClass();
- StudentList.Sort(sc);
Run the application.
This time, the list is sorted by Name even after providing a default sort functionality in the Student class.
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.