Возврат IEnumerable с использованием - PullRequest
2 голосов
/ 22 октября 2010

Интересная проблема, с которой я столкнулся, которая имеет смысл.У меня есть общий метод, например, так:

public TResult Run<TResult>(Func<SqlDataReader, TResult> resultDelegate)
{
   TResult result;

   using (SqlDataReader reader = command.ExecuteReader()) // command is SqlCommand with attached SqlConnection
   {
      result = resultsDelegate(reader);
   }

   // Some other unrelated code (but that's why result has a variable)

   return result;
}

В одном случае тип возвращаемого значения resultDelegate (TResult) равен IEnumerable<object>.Проблема в том, что функция Run немедленно возвращается из-за отложенного выполнения, освобождая SqlDataReader.Позже в коде, когда я пытаюсь прочитать результаты (что делает делегат reader.Read(), я получаю InvalidOperationException: Invalid attempt to call Read when reader is closed.

, мне трудно найти лучший способ обойти это. Я знаю,Я могу вернуть конкретный список, но я хотел бы избежать этого, если это возможно. Я также могу переместить оператор using внутри делегата, но еще раз, если я могу избежать этого для каждого делегата, это было бы неплохо. Любые идеи?

1 Ответ

5 голосов
/ 22 октября 2010

Возможно:

public TResult Run<TResult>(Func<SqlDataReader, TResult> resultDelegate)
{
   TResult result;

   using (SqlDataReader reader = command.ExecuteReader()) // command is SqlCommand with attached SqlConnection
   {
      result = resultsDelegate(reader);
      if (typeof(TResult) == typeof(IEnumerable<object>)) 
      {
         var enumerable = result as IEnumerable<object>;
         if (enumerable != null) 
         {
            result = enumerable.ToList();  
         }
      }
   }

   // Some other unrelated code (but that's why result has a variable)

   return result;

}
...