Actually it doesn't have to be an IDataReader
.
I had a function something like this:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
while (dr.Read())
{
yield return new MyClass(dr);
}
CloseDBConnections();
}
This was working fine until I refactored it like so:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
try
{
return ProcessReader(dr);
} finally {
CloseDBConnections();
}
}
public IEnumerable<MyClass> ProcessReader(IDataReader dr)
{
while (dr.Read())
{
yield return new MyClass(dr);
}
}
This doesn't work because when the CloseDBConnections()
is executed the enumeration has not yet been processed.
Calling .ToList()
on the return from GetObjects
is what actually executes the enumeration but by then the connection has already been destroyed and the IDataReader
fails.
In my instance CloseDBConnections
cannot be called from within the new ProcessReader
function because the IDataReader
could have come from some other source (the whole point of re-factoring in this instance)
Is there a sensible workaround for this or will I have to duplicate the enumerating code?
I tried putting the call to ProcessReader
as yield return
instead of return
but this doesn't work because C# (understandably) thinks I am trying to add an IEnumerable
to the IEnumerable
!