|
||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe This code sample demonstrates the declaration of a
BackgroundThe idea for this library came about as I was working on an unrelated project that manages a list on two different sort orders. Initially I used a list that was sorted on the most important sort order, and a clumsy property and filter which allowed iteration on the second sort order. I knew it was a total kludge, but it worked. Before beginning this library, I searched for this type of functionality in publicly available code, with no luck. It seems like a fairly common problem, easily encountered in routine scenarios:
The List<T> class in the
The Using the CodeThis code example demonstrates the declaration of a The public class Person : System.IEquatable<Person>
{
public enum Profession
{
Teacher,
Nurse,
Barber,
Welder,
Carpenter,
Lawyer
};
private string _name;
private int _age;
private Profession _career;
private static int _static_sequence = 0;
private int _sequence;
public Person (string name, int age,
Profession career)
{
_name = name;
_age = age;
_career = career;
lock (typeof (Person))
{
_sequence = ++_static_sequence;
}
}
public string Name { get { return _name; } }
public int Age { get { return _age; } }
public Profession Career { get { return _career; } }
public int Sequence { get { return _sequence; } }
public bool Equals (Person p)
{
return Sequence == p.Sequence;
}
}
Note the following points about the
The next step is to define an enumerator and three custom classes which are to be used as arguments to the // declare the enumerator which defines the sort orders
// that we want on the Person class
private enum PersonSortCriteria
{
Name,
Age,
Career
};
public class NameComparer :
MultiList<Person>.ITypeComparer<string>,
IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Name.CompareTo (p2.Name);
}
public int Compare (Person p, string name)
{
return p.Name.CompareTo (name);
}
}
public class AgeComparer :
MultiList<Person>.ITypeComparer<int>,
IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Age - p2.Age;
}
public int Compare (Person p, int age)
{
return p.Age - age;
}
}
public class CareerComparer :
MultiList<Person>.ITypeComparer<Person.Profession>,
IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Career.CompareTo (p2.Career);
}
public int Compare (Person p, Person.Profession career)
{
return p.Career.CompareTo (career);
}
}
The last step is to instantiate the three comparer objects and the NameComparer nameComparer = new NameComparer ();
AgeComparer ageComparer = new AgeComparer ();
CareerComparer careerComparer = new CareerComparer ();
MultiList<Person> ml =
new MultiList<Person> (
typeof (PersonSortCriteria), nameComparer,
ageComparer, careerComparer);
After this, adding objects to the list is straightforward. // add four Person objects to the MultiList
Person Jim = new Person ("Jim", 42,
Person.Profession.Teacher);
ml.Add (Jim);
ml.Add (new Person ("Susan", 29,
Person.Profession.Lawyer));
ml.Add (new Person ("Arthur", 22,
Person.Profession.Barber));
ml.Add (new Person ("Ellen", 29,
Person.Profession.Teacher));
A list can be searched for an index or for the actual object. It might be preferable to search for an index if you're not sure if a match will be found. If a match is not found, index searches return The following examples demonstrate the use of the index methods. Searching for List IndexesThere are two types of searches that can be done on a // return the index of Jim in the name sort list
int index = ml.FindIndex (PersonSortCriteria.Name, Jim);
// return the index of Jim in the age sort list
index = ml.FindIndex (PersonSortCriteria.Age, Jim);
The second type of search uses a data type that corresponds to a particular sort order. // return the index of Susan in the name sort list
int index = ml.FindIndex<string>
(PersonSortCriteria.Name, nameComparer, "Susan");
// return the index of the first Person with an age of 29
index = ml.FindIndex<int>
(PersonSortCriteria.Age, ageComparer, 29);
// return the index of the first Person
// with a career of Barber
index = ml.FindIndex<Person.Profession>
(PersonSortCriteria.Career, careerComparer,
Person.Profession.Barber);
The ml.ActiveList = PersonSortCriteria.Age;
// return the index of the first Person with an age of 29
int index = ml.FindIndex<int>
(ageComparer, 29);
When an index is obtained, the object can be accessed in a couple of ways. In the previous code example, the // note that we first check to see that a valid index was
// returned, before accessing the list element.
if (index != MultiList.NotFound)
{
Person match = ml[index];
}
You may also access any of the lists using the int index = ml.FindIndex<string>
(PersonSortCriteria.Name, nameComparer, "Susan");
if (index != MultiList.NotFound)
{
Person match = ml.GetObject (PersonSortCriteria.Name,
index);
}
Searching for Actual ObjectsThe Person match;
try
{
match = ml.Find<string>
(PersonSortCriteria.Name, nameComparer, "Susan");
}
catch (MultiListObjectNotFoundException)
{
// not found
}
// set the active list to age, and use the
// TryFind method to search
ml.ActiveList = PersonSortCriteria.Age;
if (true == TryFind<string>
(ageComparer, 29, out match))
{
// a match was found
}
Searching for Multiple ObjectsSeveral methods are available that return multiple objects or indexes when duplicates exist. IndexRange range = ml.FindIndexes<int>
(PersonSortCriteria.Age, ageComparer, 29);
if (range.Count > 0)
{
// one or more matches was found
}
Person[] matches = ml.FindMultiple<int>
(PersonSortCriteria.Age, ageComparer, 29);
if (matches.Length > 0)
{
// one or more matches was found
}
Points of InterestThe unit test code for this project requires NUnit 2.4.3. History
|
|||||||||||||||||||||||||||||||||||||||||||||||