Answered by:
Sorting Complex Type Using IComparer

Question
-
User1231829591 posted
Hi, I am trying to sort my employees based on ManagementLevel by implementing IComplarer interface. However, for the Compare method of the IComparer interface to work a separate class must be created.
The following is my Employee class definition which implements IComparer's Compare method:
public class Employee : IComparer<Employee> { public string Name { get; set; } public int Salary { get; set; } public ManagementLevel ManageLvl { get; set; } public int Compare(Employee emp, Employee otherEmp) { return emp.ManageLvl.CompareTo(otherEmp.ManageLvl); } }
The following is my Enum definition
public enum ManagementLevel { CEO = 1, CFO = 2, CTO = 3, RegionalManager = 4 }
The following adds , sorts, then reverse sorts the list of employees:
List<Employee> employeeList = new List<Employee>(); employee emp = new Employee(); emp.Name = txtName.Text; emp.Salary = Convert.ToInt32(txtSalary.Text); emp.ManageLvl = (ManagementLevel)Enum.Parse(typeof(ManagementLevel), txtManagementLevel.Text); employeeList.Add(emp); employeeList.Sort(); employeeList.Reverse();
I am getting the error below
At least one object must implement IComparable.
As stated above the Sort method does not work. I was only able to make the Compare method of the ICompare interface sort the way I want by creating a separate class but why can't I implement it in the Employee class, thanks in advance for your reply.
Tuesday, January 12, 2016 5:59 AM
Answers
-
User-434868552 posted
TIMTOWTDI
use IComparable instead of IComparer
this code which works in LINQPad5 is mostly your code from above with fixed typos. http://linqpad.net
public enum ManagementLevel { CEO = 1, CFO = 2, CTO = 3, RegionalManager = 4 }
public class Employee : IComparable<Employee> { public string Name{ get; set; } public int Salary{ get; set; } public ManagementLevel ManageLvl{ get; set; } public int CompareTo(Employee employee) { return this.ManageLvl.CompareTo(employee.ManageLvl); } }
void Main() { List<Employee> employeeList = new List<Employee>(); Employee emp = new Employee(); emp.Name = "ManyTitles"; emp.Salary = 1234; emp.ManageLvl = ManagementLevel.RegionalManager; employeeList.Add(emp); Employee cto = new Employee(); cto.Name = "CTO"; cto.Salary = 2345; cto.ManageLvl = ManagementLevel.CTO; employeeList.Add(cto); Employee ceo = new Employee(); ceo.Name = "CEO"; ceo.Salary = 123456; ceo.ManageLvl = ManagementLevel.CEO; employeeList.Add(ceo); Employee cfo = new Employee(); cfo.Name = "CFO"; cfo.Salary = 99999; cfo.ManageLvl = ManagementLevel.CFO; employeeList.Add(cfo); employeeList.Dump("unordered"); employeeList.Sort(); employeeList.Dump("ordered"); employeeList.Reverse(); employeeList.Dump("reversed"); }
The .Dump method is provided by LINQPad5
output:unordered
List<Employee> (4 items) Name Salary ManageLvl ManyTitles 1234 RegionalManager CTO 2345 CTO CEO 123456 CEO CFO 99999 CFO
orderedList<Employee> (4 items) Name Salary ManageLvl CEO 123456 CEO CFO 99999 CFO CTO 2345 CTO ManyTitles 1234 RegionalManager
reversedList<Employee> (4 items) Name Salary ManageLvl ManyTitles 1234 RegionalManager CTO 2345 CTO CFO 99999 CFO CEO 123456 CEO References:
https://support.microsoft.com/en-us/kb/320727 "How to use the IComparable and IComparer interfaces in Visual C#"
http://www.codedigest.com/Articles/CSHARP/84_Sorting_in_Generic_List.aspx "Sorting in C# Generic List(List<T>)"
it is not working without creating a separate classFrom the first reference above:
The role of IComparer is to provide additional comparison mechanisms. ...
Using IComparer is a two-step process.
First, declare a class that implements IComparer,
and then implement the Compare method- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 12, 2016 9:12 AM
All replies
-
User-434868552 posted
TIMTOWTDI
use IComparable instead of IComparer
this code which works in LINQPad5 is mostly your code from above with fixed typos. http://linqpad.net
public enum ManagementLevel { CEO = 1, CFO = 2, CTO = 3, RegionalManager = 4 }
public class Employee : IComparable<Employee> { public string Name{ get; set; } public int Salary{ get; set; } public ManagementLevel ManageLvl{ get; set; } public int CompareTo(Employee employee) { return this.ManageLvl.CompareTo(employee.ManageLvl); } }
void Main() { List<Employee> employeeList = new List<Employee>(); Employee emp = new Employee(); emp.Name = "ManyTitles"; emp.Salary = 1234; emp.ManageLvl = ManagementLevel.RegionalManager; employeeList.Add(emp); Employee cto = new Employee(); cto.Name = "CTO"; cto.Salary = 2345; cto.ManageLvl = ManagementLevel.CTO; employeeList.Add(cto); Employee ceo = new Employee(); ceo.Name = "CEO"; ceo.Salary = 123456; ceo.ManageLvl = ManagementLevel.CEO; employeeList.Add(ceo); Employee cfo = new Employee(); cfo.Name = "CFO"; cfo.Salary = 99999; cfo.ManageLvl = ManagementLevel.CFO; employeeList.Add(cfo); employeeList.Dump("unordered"); employeeList.Sort(); employeeList.Dump("ordered"); employeeList.Reverse(); employeeList.Dump("reversed"); }
The .Dump method is provided by LINQPad5
output:unordered
List<Employee> (4 items) Name Salary ManageLvl ManyTitles 1234 RegionalManager CTO 2345 CTO CEO 123456 CEO CFO 99999 CFO
orderedList<Employee> (4 items) Name Salary ManageLvl CEO 123456 CEO CFO 99999 CFO CTO 2345 CTO ManyTitles 1234 RegionalManager
reversedList<Employee> (4 items) Name Salary ManageLvl ManyTitles 1234 RegionalManager CTO 2345 CTO CFO 99999 CFO CEO 123456 CEO References:
https://support.microsoft.com/en-us/kb/320727 "How to use the IComparable and IComparer interfaces in Visual C#"
http://www.codedigest.com/Articles/CSHARP/84_Sorting_in_Generic_List.aspx "Sorting in C# Generic List(List<T>)"
it is not working without creating a separate classFrom the first reference above:
The role of IComparer is to provide additional comparison mechanisms. ...
Using IComparer is a two-step process.
First, declare a class that implements IComparer,
and then implement the Compare method- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 12, 2016 9:12 AM -
User1231829591 posted
Hi, thanks for replying. At first I wasn't clear as to why a new class had to be created to implement IComparer since I was following a tutorial online which did not explain the details on usage.
Tuesday, January 12, 2016 6:55 PM -
User303363814 posted
Alternatively, don't implement IComp* at all just use linq.
var reversedList = employeeList.OrderByDescending(e => e.ManageLvl);
Tuesday, January 12, 2016 10:27 PM