Datasheet
The Delegate Strategy
x
13
private List<T> data = new List<T>();
// ...
public T[] FindAll(SearchProc<T> algorithm)
{
List<T> results = new List<T>();
foreach (T i in data)
{
if (algorithm(i))
results.Add(i);
}
return results.ToArray();
}
}
C# 2.0 saw much of this coming and predefi ned those delegate types already as part of the FCL: the
Predicate<T> and Func<T> delegate types, the fi rst used to yield a bool result (like the SearchProc
previously defi ned) and the other used to simply “act” upon the value passed in (such as printing it
to the console or something similar). In the spirit of “Code not written or removed means code not
written with bugs, or maintained so that bugs are introduced later,” this means that the code can be
refactored to remove the redundant delegate type declaration and use those already defi ned:
class Database<T> where T : class
{
private List<T> data = new List<T>();
public Database() { }
public void Add(T i) { data.Add(i); }
public T Find(Predicate<T> algorithm)
{
foreach (T it in data)
if (algorithm(it))
return it;
return null;
}
public T[] FindAll(Predicate<T> algorithm)
{
List<T> results = new List<T>();
foreach (T it in data)
if (algorithm(it))
results.Add(it);
return results.ToArray();
}
}
Other kinds of operations on the Database not yet implemented (but should be) quickly come to
mind, such as taking some kind of action on each of those returned objects. To be precise, three
kinds of operations should be supported on
Database<T>: Filter, Map, and Reduce:
delegate U Accumulator<T, U>(T src, U rslt);
class Database<T> where T : class
{
private List<T> data = new List<T>();
c01.indd 13c01.indd 13 10/1/2010 3:20:37 PM10/1/2010 3:20:37 PM










