Sorting arrays is a common programming task, and the new utility interface in .NET makes it a breeze. The primary benefit of this technique is that you can decouple the sorting class from the contents of the array. To demonstrate, I’ll keep it simple and sort an array of strings written in C#:
names = new string;
string = “Erika Anhood”;
string = “Ayal Belling”;
string = “Jack Daniels”;
string = “Kris Kringle”;
string = “Santa Claus”;
To sort this array in alphabetical order, we'll leverage the static sort method in the Array class to sort the names array. The Array.Sort method will sort the array in place, meaning we don’t have to create another array. The code in Listing A will sort the array and then use the foreach statement to loop through it and output the values to the console.
Let’s take it up a notch and create an Employee class, as shown in Listing B.
In Listing C, we create an array of Employee.
Let’s again try to sort it using the Array.Sort(). You’ll find the code in Listing D throws an IComparer exception on the Array.Sort line.
The error occurs because Array.Sort doesn’t know how to sort the employee array. Should the sort be by the Firstname field? Lastname field? The exception simply means that you haven’t specified how the sort should occur. You can do this by implementing the IComparable interface on the Employee class:
public class Employee: IComparable
Use the Expand Class Viewer in Visual Studio .NET until you see the IComparable interface. Right-click on it and select Add | Implement Interface. After doing this, you should see the stub code for the interface implementation.
The IComparable interface has a CompareTo with the following signature:
public abstract virtual System.Int32 CompareTo ( System.Object obj )
This method returns an integer that indicates the relative order of the two objects being compared (comparands). Three return values are possible:
- · A negative value indicates that the current instance is less than obj.
- · Zero indicates that the current instance is equal to obj.
- · A positive value indicates that the current instance is greater than obj.
For the Employee class we want to sort on Lastname, Firstname so we have the implementation of the CompareTo method shown in Listing E.
Now if you rerun the program, you will see that the array is sorted by last name. We’re just warming up though; consider this: What if we want to sort the array by wage? The class can implement the IComparable interface only once.
This is where the IComparer interface makes its entry. Closer inspection of the Array.Sort reveals an overload version that takes an object that implements IComparer. You could make the Employee class implement IComparer, but that would be a mistake—you'd again be limited to a single sort for the IComparer interface. The solution is simple: utility classes. Each utility class implements IComparer. For an example, see Listing F.
You may be tempted to create the utility classes as nested classes within Employee. This is perfectly acceptable; however, it may be advisable to create them in separate files to facilitate development by more than one developer. Otherwise, only a single developer can check out the file from Source Safe.
As it stands, the sort accommodates only ascending or descending sort. A simple public Boolean flag, sortAscending, lets you determine the sort order:
public bool sortAscending;
Now in your Compare method, simply check the flag. If it indicates a descending sort, reverse the order of the comparands.
There you have it. By leveraging the utility interface you can maximize your sorts because sorting is not tied to the contents of the array.