实际上,它不必是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/

10-16 05:18