2010-01-08

if-read-do-while-read part 2

I just received a comment on my previous post about the if-read-do-while-read construction. Tanton suggests that I could create a method that encapsulates this construction, using delegates for the before, during and after steps. Here's a quick version of an extension method on IDataReader that does this:

public static class DataReaderExtensions
{
  public static void ReadAll(
    this IDataReader reader,
    Action before,
    Action<IDataRecord> during,
    Action after)
  {
    if (reader == null) throw new ArgumentNullException("reader");

    if (reader.Read())
    {
      if (before != null)
        before();
      
      do
      {
        if (during != null)
          during(reader);
      }
      while (reader.Read());
      
      if (after != null)
        after();
    }
  }
}

And here's a rewrite of the HTML-example, using this extension method:

StringBuilder html = new StringBuilder();
using (IDataReader reader = command.ExecuteReader())
  reader.ReadAll(
    () => html.Append("<ul>"),
    record => html.AppendFormat("<li>{0}", record.GetValue(0)),
    () => html.Append("</ul>"));

It surely is shorter, but I'm not entirely convinced it's cleaner.