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