Using generics to build generic data logic layers

Consider exposing raw Generic collections from your data logic layers, such as:

public class PersonManager {

...

public List<Person> ListPeople(...) { ... } ;

}

When I started messing around with building applications in 2.0 I quickly wrapped Generic collections like so:

public class PersonCollection : List<Person> {

...

}

This was normally done so that I could hang a Sort method off of them:

public class PersonCollection : List<Person>, IBidirectionalSort {

...

public void Sort( string sortExpression, bool isAscending ) { ... }

}

The downside of this approach is that you end up writing fiddly code around calls to generic helper methods.

As an example, let's say that I write a nice generic helper method to page my collections:

public static void Page(ref List<T> data, int maximumRows, int startRowIndex)

where T : IDataObject, new() {

if (data.Count > 0) {

if (maximumRows > 0 && startRowIndex >= 0) {

List<T> tmpColl = null;

int remainingRowCount = data.Count - startRowIndex;

int count = (remainingRowCount >= maximumRows) ? maximumRows : remainingRowCount;

if (count > 0) {

tmpColl = new List<T>();

tmpColl.AddRange(data.GetRange(startRowIndex, count));

}

data = tmpColl;

}

}

}

If I've wrapped my collection – as per the PersonCollection example – then using the generic Page method will require temporary object creation when I'm calling it, something like:

public PersonCollection ListPeople(...) {

...

PersonCollection people = FillList( reader ) ;

List<Person> tmp = Page( people, 20, 0 ) ;

PersonCollection peopleToReturn = new PersonCollection() ;

peopleToReturn.AddRange( tmp ) ;

return peopleToReturn ;

}

So, you can see that by the time we have many generic methods, working with temporary objects becomes cumbersome. Exposing List<Person> from this method would lead you to build your surrounding methods – such as FillList and Page – to work with your code better but will also lead to leaner code:

public List<Person> ListPeople(...) {

...

List<Person> people = FillList<Person>( reader ) ;

return Page<Person>( people, 20, 0 ) ;