2

实际上它不一定是一个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()return fromGetObjects是实际执行枚举的内容,但到那时连接已经被破坏并且IDataReader失败。

在我的实例CloseDBConnections中,不能从新ProcessReader函数中调用,因为它IDataReader可能来自其他来源(在这个实例中重构的重点)

是否有合理的解决方法,或者我是否必须复制枚举代码?

我尝试调用ProcessReaderasyield return而不是,return但这不起作用,因为 C#(可以理解)认为我正在尝试将一个添加IEnumerableIEnumerable!

4

2 回答 2

3

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();
  }
}
于 2013-07-25T09:05:32.093 回答
3

不漂亮,但这应该工作。

public IEnumerable<MyClass> GetObjects() 
{
  IDataReader dr = GetSomeDataReader();
  try
  {
    foreach (var result in ProcessReader(dr))
    {
      yield return result;
    }
  } finally {
    CloseDBConnections();
  }
}
于 2013-07-25T08:44:45.087 回答