实际上,它不必是IDataReader
。
我有一个类似这样的功能:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
while (dr.Read())
{
yield return new MyClass(dr);
}
CloseDBConnections();
}
直到我像这样重构它之前,它都运行良好:
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);
}
}
这不起作用,因为在执行
CloseDBConnections()
时,枚举尚未处理。实际执行枚举的是在
.ToList()
的返回值上调用GetObjects
的方法,但是到那时连接已被破坏并且IDataReader
失败。在我的实例中,无法从新的
CloseDBConnections
函数中调用ProcessReader
,因为IDataReader
可能来自其他来源(此实例中的整个重构点)是否有一个合理的解决方法,还是我必须重复枚举代码?
我尝试将呼叫作为
ProcessReader
而不是yield return
放置到return
,但这不起作用,因为C#(可以理解)认为我正在尝试向IEnumerable
添加IEnumerable
! 最佳答案
如何通过回调在CloseDBConnections
中调用ProcessReader
?
public IEnumerable<MyClass> GetObjects()
{
return ProcessReader(GetSomeDataReader(), CloseDBConnections);
}
public IEnumerable<MyClass> ProcessReader(IDataReader dr, Action OnFinished)
{
try
{
while (dr.Read())
yield return new MyClass(dr);
}
finally
{
if (OnFinished != null)
OnFinished();
}
}
关于c# - yield 返回完成后关闭IDataReader,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17852918/