To solve this problem, the Employee
class needs to implement the IComparable
interface 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 Employee
parameter, and you compare the current instance (represented by this) of the Employee
class's FirstName
property to the parameter's FirstName
property. Here, you use the CompareTo()
method of the String
class ( FirstName
is of String
type) 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 List
object containing Employee
objects, the Employee
objects 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 Employee
objects using the LastName
instead 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 Salary
property:
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 Employee
objects are sorted is fixed by the implementation of the CompareTo()
method. If CompareTo()
compares using the FirstName
property, the sort is based on the FirstName
property. To give users a choice of which field they want to use to sort the objects, you can use the IComparer
interface.
To do so, first declare a private class within the Employee
class 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 SalaryComparer
class implements the IComparer
interface. IComparer
has one method — Compare()
— that you need to implement. It compares the salary of two Employee
objects.
To use the SalaryComparer
class, declare the SalarySorter
static property within the Employee
class so that you can return an instance of the SalaryComparer
class:
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 Employee
objects using the default, or specify the SalarySorter
property:
employees.Sort(); //---sort using FirstName (default)---
employees.Sort(Employee.SalarySorter); //---sort using Salary---
To allow the Employee
objects to be sorted using the LastName
property, you could define another class (say LastNameComparer
) that implements the IComparer
interface and then declare the SalarySorter
static 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);
Читать дальше