To solve this problem, the Employeeclass needs to implement the IComparableinterface and then implement the CompareTo()method:
public class Employee : IComparable {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
public override string ToString() {
return FirstName + ", " + LastName + " $" + Salary;
}
public int CompareTo(Employee emp) {
return this.FirstName.CompareTo(emp.FirstName);
}
}
The CompareTo()method takes an Employeeparameter, and you compare the current instance (represented by this) of the Employeeclass's FirstNameproperty to the parameter's FirstNameproperty. Here, you use the CompareTo()method of the Stringclass ( FirstNameis of Stringtype) to perform the comparison.
The return value of the CompareTo(obj)method has the possible values as shown in the following table.
| Value |
Meaning |
| Less than zero |
The current instance is less than obj. |
| Zero |
The current instance is equal to obj. |
| Greater than zero |
The current instance is greater than obj. |
Now, when you sort the Listobject containing Employeeobjects, the Employeeobjects will be sorted by first name:
employees.Sort();
foreach (Employee emp in employees)
Console.WriteLine(emp.ToString());
These statements produce the following output:
Brian, Will $3000
Howard, Mark $1500
John, Smith $4000
Margaret, Anderson $3000
To sort the Employeeobjects using the LastNameinstead of FirstName, simply change the CompareTo()method as follows:
public int CompareTo(Employee emp) {
return this.LastName.CompareTo(emp.LastName);
}
The output becomes:
Margaret, Anderson $3000
Howard, Mark $1500
John, Smith $4000
Brian, Will $3000
Likewise, to sort by salary, you compare the Salaryproperty:
public int CompareTo(Employee emp) {
return this.Salary.CompareTo(emp.Salary);
}
The output is now:
Howard, Mark $1500
Margaret, Anderson $3000
Brian, Will $3000
John, Smith $4000
Instead of using the CompareTo()method of the type you are comparing, you can manually perform the comparison, like this:
public int CompareTo(Employee emp) {
if (this.Salary < emp.Salary) return -1;
else if (this.Salary == emp.Salary) return 0;
else return 1;
}
How the Employeeobjects are sorted is fixed by the implementation of the CompareTo()method. If CompareTo()compares using the FirstNameproperty, the sort is based on the FirstNameproperty. To give users a choice of which field they want to use to sort the objects, you can use the IComparerinterface.
To do so, first declare a private class within the Employeeclass and call it SalaryComparer.
public class Employee : IComparable {
private class SalaryComparer : IComparer {
public int Compare(Employee e1, Employee e2) {
if (e1.Salary < e2.Salary) return -1;
else if (e1.Salary == e2.Salary) return 0;
else return 1;
}
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
public override string ToString() {
return FirstName + ", " + LastName + " $" + Salary;
}
public int CompareTo(Employee emp) {
return this.FirstName.CompareTo(emp.FirstName);
}
}
The SalaryComparerclass implements the IComparerinterface. IComparerhas one method — Compare()— that you need to implement. It compares the salary of two Employeeobjects.
To use the SalaryComparerclass, declare the SalarySorterstatic property within the Employeeclass so that you can return an instance of the SalaryComparerclass:
public class Employee : IComparable {
private class SalaryComparer : IComparer {
public int Compare(Employee e1, Employee e2) {
if (e1.Salary < e2.Salary) return -1;
else if (e1.Salary == e2.Salary) return 0;
else return 1;
}
}
public static IComparer SalarySorter {
get { return new SalaryComparer(); }
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
public override string ToString() {
return FirstName + ", " + LastName + " $" + Salary;
}
public int CompareTo(Employee emp) {
return this.FirstName.CompareTo(emp.FirstName);
}
}
You can now sort the Employeeobjects using the default, or specify the SalarySorterproperty:
employees.Sort(); //---sort using FirstName (default)---
employees.Sort(Employee.SalarySorter); //---sort using Salary---
To allow the Employeeobjects to be sorted using the LastNameproperty, you could define another class (say LastNameComparer) that implements the IComparerinterface and then declare the SalarySorterstatic property, like this:
public class Employee : IComparable {
private class SalaryComparer : IComparer {
public int Compare(Employee e1, Employee e2) {
if (e1.Salary < e2.Salary) return -1;
else if (e1.Salary == e2.Salary) return 0;
else return 1;
}
}
private class LastNameComparer : IComparer {
public int Compare(Employee e1, Employee e2) {
return e1.LastName.CompareTo(e2.LastName);
Читать дальше