Mega Code Archive

 
Categories / C# / Language Basics
 

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);         }     } }