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