Если я правильно помню, когда я использовал yield внутри с использованием блоков SqlConnection
, я получал исключения времени выполнения.
using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
yield reader[0];
}
// Call Close when done reading.
reader.Close();
}
Эти проблемы были решены, когда я заменил yield
списком, куда я добавлял элементы на каждой итерации.
Та же проблема еще не возникала со мной, когда внутри с использованием блоков StreamReader
using (var streamReader = new StreamReader(fileName))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
}
Есть ли какое-либо объяснение, почему в первом случае возникли исключения а не в последнем? Целесообразна ли эта конструкция?
РЕДАКТИРОВАТЬ Чтобы получить ошибку (раннее устранение), которую я делал в прошлом, вы должны вызвать первый метод ниже:
IEnumerable<string> Read(string fileName)
{
using (var streamReader = new StreamReader(fileName))
{
return Read(streamReader);
} // Dispose will be executed before ReadLine() because of deffered execution
}
IEnumerable<string> Read(StreamReader streamReader)
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
}
Та же ошибка может быть достигнута с помощью других способов отсрочки выполнения, например System.Linq.Enumerable.Select ()