if-read-do-while-read

Here’s a construction I occasionally need when reading items from a IDataReader: to execute some code before and after reading through the IDataReader, but only if there are rows in the IDataReader.

One option is to use a boolean variable that determines whether the collection has items, like this:

using (IDataReader reader = command.ExecuteReader())
{
  bool hasRows = false;
  while (reader.Read())
  {
    if (!hasRows)
    {
      hasRows = true;
      Before();
    }

    During();
  }

  if (hasRows)
  {
    After();
  }
}

But the following construction (which I call the if-read-do-while-read construction) does not need the boolean variable and is cleaner:

using (IDataReader reader = command.ExecuteReader())
{
  if (reader.Read())
  {
    Before();

    do
    {
      During();
    }
    while (reader.Read());

    After();
  }
}

Here’s a practical example: creating HTML-code with a UL-list for the data, but only if there are items:

StringBuilder html = new StringBuilder();
using (IDataReader reader = command.ExecuteReader())
{
  if (reader.Read())
  {
    html.Append("<ul>");

    do
    {
      html.AppendFormat(
        "<li>{0}",
        reader.GetValue(0));
    }
    while (reader.Read());

    html.Append("</ul>");
  }
}

You could use the same technique on an IEnumerable<T>, but you wouldn’t be able to use foreach anymore:

using (var enumerator = collection.GetEnumerator())
{
  if (enumerator.MoveNext())
  {
    Before();

    do
    {
      var item = enumerator.Current;
      During();
    }
    while (enumerator.MoveNext());

    After();
  }
}