Фон: У меня есть куча строк, которые я получаю из базы данных, и я хочу вернуть их. Традиционно, это было бы что-то вроде этого:C# IEnumerator/структура доходности потенциально плохая?
public List<string> GetStuff(string connectionString)
{
List<string> categoryList = new List<string>();
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
categoryList.Add(sqlDataReader["myImportantColumn"].ToString());
}
}
}
return categoryList;
}
Но я полагаю, что потребитель захочет итерацию по элементам и не заботится о многом другом, и я хотел бы, чтобы не боксировал себя в в список, как таковой, поэтому, если я верну IENumerable, все будет хорошо/гибко. Так я думал, что я мог бы использовать конструкцию типа «возврат выход», чтобы справиться с этим ... что-то вроде этого:
public IEnumerable<string> GetStuff(string connectionString)
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
yield return sqlDataReader["myImportantColumn"].ToString();
}
}
}
}
Но теперь, когда я читаю немного больше о доходности (на сайтах, как это .. .msdn, похоже, не упоминает об этом), это, по-видимому, ленивый оценщик, который поддерживает состояние популяра, ожидая, что кто-то попросит следующее значение, а затем запустит его, пока не вернет следующее значение.
В большинстве случаев это кажется прекрасным, но с вызовом DB это звучит немного рискованно. Как несколько надуманный пример, если кто-то просит IEnumerable из того, что я заполняю из вызова БД, получает его половину, а затем застревает в цикле ... насколько я вижу, мое соединение с БД происходит оставаться навсегда.
Похоже, что в некоторых случаях возникает проблема, если итератор не заканчивается ... Я что-то упустил?
Спасибо за редактирование, Джон ... это то, что я получаю для набора текста на лету. – Beska
Пока ваш потребитель называет «Dispose» на IEnumerator, вы в безопасности. См. Мои публикации ниже. – tofi9