Daily Archives: September 22, 2008

Extend a Generic List to Provide Dictionary-Like Lookups

 

Welcome to a quick and dirty example in which I’ll make use of interfaces, inheritance and generics. I was working with some code that did a lot of iterating over collections to find objects with a particular ID. This is an abstracted example of what I did to simplify and centralize that code in a reusable manner.

If you are using Visual Studio 2008, you could achieve the same kind of reuse with an extension method on your generic list. The project I was working on was in .NET 2.0 and Visual Studio 2005.

This method returns a student’s course based on its ID. The student object here is a private class member. The CurrentCourses property is a List<Course> collection.

private Course FindCourseOld(int id)
{
    foreach (var course in _student.CurrentCourses)
    {
        if (course.ID == id)
        {
            return course;
        }
    }

    return null;
}
 

It’s pretty simple, but suppose you had a dozen or more types with an ID property that were all queries like this? It smells like an opportunity to do some refactoring. We need to keep all the functionality of the List<T> generic collection, including sorting, index operations, and enumerating, but we want to provide a dictionary-type of lookup on the ID property. Let’s inherit from List<T> and add a method to perform our lookup.

Before an object can be stored in this new collection, our child of List<T>, that we are going to create, we need to ensure it has an ID property on which we can operate. To that end, I present to you the IHasIdentifier interface. I know it’s not grammatically correct, but I think it gets the point across.

public interface IHasIdentifier
{
    int ID { get; set; }
}

 

The new interface has a single property named ‘ID’, which many of the types you might consider using in our collection may already have. Next up is the IdentityList<T> itself. The implementation I have here is very simple. There is just a single method, GetItemByID, added to the base class, List<T>.

public class IdentityList<T> : List<T> where T : IHasIdentifier
{
    public T GetItemByID(int id)
    {
        foreach (var obj in this)
        {
            if (obj.ID == id)
            {
                return obj;
            }
        }

        return default(T);
    }
}

 

We’re inheriting from List<T> and specifying that T must implement IHasIdentifier. Now, in the GetItemByID method, we can do our iteration to find the object with the given ID and return it. Finally, let’s take a look at the FindCourseNew method which uses our IdentityList<T> collection.

private Course FindCourseNew(int id)
{
    return _student.CurrentCourses.GetItemByID(id);
}

 

The code here is much cleaner, and there could be more opportunity for code reuse with the IdentityList<T>. Many of the dictionary type of methods could be adapted and used within this collection. You can download the sample code here. As always, any and all feedback is welcome!

 

 

Dew Drop – September 22, 2008

 

Design / Methodology / Testing

 

Web Development

 

.NET / Visual Studio

 

Silverlight / WPF

 

Database

 

Events / Community

 

Miscellaneous

 

More Link Collections

 

Book of the Day