Wednesday, February 21, 2007

Sorting Generic Lists

One of the things I like best about the use of Generics is the ability to define your own sorting functionality and apply it to a List. Much in the same way you can predefine your own Find mechanism using predicates, you can establish a way to sort your list of Generics when they don't contain native datatypes such as int or string.

In this example we'll take a look at how to sort a Generic list using the IComparer interface.

First of all, let's establish a class of type Dog, and give it three properties. The first property we'll call Species, and the next property we'll call Age. The final property we'll call Name.

public class Dog
{
private int _age;
private string _species;
private string _name;

public string Name
{
get{ return _name; }
set{ _name = value; }
}
public int Age
{
get{ return _age; }
set{ _age = value; }
}
public string Species
{
get{ return _species; }
set{ _species = value; }
}
}

Now that we have that we can create a list of four dogs like so:

Dog max = new Dog();
max.Age = 8;
max.Species = "Labrador"
max.Name = "Max"

Dog spike = new Dog();
spike.Age = 3;
spike.Species = "Rottweiler"
spike.Name = "Spike"

Dog princess = new Dog();
princess.Age = 5;
princess.Species = "Poodle"
princess.Name = "Princess"

Dog wolfy = new Dog();
wolfy.Age = 10;
wolfy.Species = "Husky"
wolfy.Name = "Wolfy"

List<Dog> dogs = new List<Dog>();

dogs.Add(max);
dogs.Add(spike);
dogs.Add(princess);
dogs.Add(wolfy);

Now I'd like to be able to sort a few different ways, and I can do this by providing an object that implements an IComparer interface of type Dog, like so:

public class DogAgeComparer : IComparer<Dog>
{

}

Now that I have my class, let's implement the interface:

public class DogAgeComparer : IComparer<Dog>
{
#region IComparer<Dog> Members

public int Compare(Dog x, Dog y)
{
return x.Age.CompareTo(y.Age);
}

#endregion
}

Now that we have that, we can sort our list based on the dog's age:

dogs.Sort(new DogAgeComparer());

This will sort the list in the appropriate order of age.

Similarly, we can use a different object for Name and have that available as well.

public class DogNameComparer : IComparer<Dog>
{
#region IComparer<Dog> Members

public int Compare(Dog x, Dog y)
{
return x.Name.CompareTo(y.Name);
}

#endregion
}

Now sort the list:

dogs.Sort(new DogNameComparer());

And there you have it! Quick and easy sorting of your objects.

Happy sorting!

 

Rob