Using a delegate with a container class
to sort the collection and return a sorted array using different
sort criteria
/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
// SortEmpl.cs -- Demonstrates using a delegate with a container class to
// sort the collection and return a sorted array using different
// sort criteria.
//
// Compile this program with the following command line:
// C:>csc SortEmpl.cs
using System;
using System.ComponentModel;
namespace nsDelegates
{
public class SortEmpl
{
// Declare an enum for the sort methods.
enum SortBy {Name, ID, ZIP};
// Create a container to get the clsEmployee object collection
static public clsEmployeeContainer container = new clsEmployeeContainer ();
static public void Main ()
{
container.Add (new clsEmployee ("John", "Smith", "87678", 1234));
container.Add (new clsEmployee ("Marty", "Thrush", "80123", 1212));
container.Add (new clsEmployee ("Milton", "Aberdeen", "87644", 1243));
container.Add (new clsEmployee ("Marion", "Douglas", "34567", 3454));
container.Add (new clsEmployee ("Johnathon", "Winters", "53422", 3458));
container.Add (new clsEmployee ("William", "Marmouth", "12964", 3658));
container.Add (new clsEmployee ("Miles", "O'Brien", "63445", 6332));
container.Add (new clsEmployee ("Benjamin", "Sisko", "57553", 9876));
// Show the unsorted employee list.
Console.WriteLine ("Unsorted employee list:");
ComponentCollection collectionList = container.GetEmployees();
foreach (clsEmployee emp in collectionList)
{
Console.WriteLine ("\t" + emp);
}
// Sort the employees by last name and show the list.
Console.WriteLine ("\r\nSorted by last name:");
clsEmployee [] arr = SortList (SortBy.Name);
foreach (clsEmployee emp in arr)
{
Console.WriteLine ("\t" + emp);
}
// Sort the employees by ID number and show the list.
Console.WriteLine ("\r\nSorted by employee ID:");
arr = SortList (SortBy.ID);
foreach (clsEmployee emp in arr)
{
Console.WriteLine ("\t" + emp);
}
// Sort the employees by ZIP code and show the list.
Console.WriteLine ("\r\nSorted by ZIP code:");
arr = SortList (SortBy.ZIP);
foreach (clsEmployee emp in arr)
{
Console.WriteLine ("\t" + emp);
}
}
// Define a method that will create the proper delegate according to
// the sort that is needed.
static clsEmployee [] SortList (SortBy iSort)
{
clsEmployeeContainer.CompareItems sort = null;
switch (iSort)
{
case SortBy.Name:
sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByName);
break;
case SortBy.ID:
sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByID);
break;
case SortBy.ZIP:
sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByZip);
break;
}
// Do the sort and return the sorted array to the caller.
return (container.SortItems (sort, false));
}
}
public class clsEmployee : Component
{
// Define an employee class to hold one employee's information.
public clsEmployee (string First, string Last, string Zip, int ID)
{
FirstName = First;
LastName = Last;
EmployeeID = ID;
ZipCode = Zip;
}
public string FirstName;
public string LastName;
public string ZipCode;
public int EmployeeID;
// Define a method to sort by name
static public int CompareByName (object o1, object o2)
{
clsEmployee emp1 = (clsEmployee) o1;
clsEmployee emp2 = (clsEmployee) o2;
return (String.Compare (emp1.LastName, emp2.LastName));
}
// Define a method to sort by ZIP code
static public int CompareByZip (object o1, object o2)
{
clsEmployee emp1 = (clsEmployee) o1;
clsEmployee emp2 = (clsEmployee) o2;
return (String.Compare (emp1.ZipCode, emp2.ZipCode));
}
// Define a method to sort by employee ID number.
static public int CompareByID (object o1, object o2)
{
clsEmployee emp1 = (clsEmployee) o1;
clsEmployee emp2 = (clsEmployee) o2;
return (emp1.EmployeeID - emp2.EmployeeID);
}
// Override ToString() for diagnostic purposes
public override string ToString ()
{
return (FirstName + " " + LastName + ", ZIP " + ZipCode + ", ID " + EmployeeID);
}
}
// Derive a class to hold the clsEmployee objects
public class clsEmployeeContainer
{
private Container cont = new Container();
public void Add (clsEmployee empl)
{
cont.Add (empl);
}
// Declare an array to return to the caller
clsEmployee [] arrEmployee;
// Declare a delegate to compare one employee object to another
public delegate int CompareItems (object obj1, object obj2);
// Define a sort function that takes a delegate as a parameter. The Reverse
// parameter can be used to reverse the sort.
public clsEmployee [] SortItems (CompareItems sort, bool Reverse)
{
// Get the clsEmployee objects in the container.
ComponentCollection employees = cont.Components;
// Create an array large enough to hold the references
arrEmployee = new clsEmployee[employees.Count];
// Copy the collection into the reference. The Container class will not
// let us sort the collection itself.
employees.CopyTo (arrEmployee, 0);
// Do a simple bubble sort. There are more efficient sorting algorithms,
// but a simple sort is all we need.
while (true)
{
int sorts = 0;
for (int x = 0; x < arrEmployee.Length - 1; ++x)
{
int result;
// Sort in the reverse order if if the Reverse parameter equals true
if (Reverse == true)
result = sort (arrEmployee[x + 1], arrEmployee[x]);
else
result = sort (arrEmployee[x], arrEmployee[x + 1]);
// Reverse the two elements if the result is greater than zero
if (result > 0)
{
clsEmployee temp = arrEmployee[x];
arrEmployee[x] = arrEmployee[x+1];
arrEmployee[x+1] = temp;
++sorts;
}
}
// If we did no sorts on this go around, the sort is complete.
if (sorts == 0)
break;
}
// Return the sorted array to the caller.
return (arrEmployee);
}
// Return the collection to the caller.
public ComponentCollection GetEmployees ()
{
return (cont.Components);
}
}
}
Related examples in the same category