Фон: у меня есть куча строк, которые я получаю из базы данных, и я хочу вернуть их. Традиционно это было бы примерно так:
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 из того, что я заполняю из вызова БД, получает его половину, а затем застревает в цикле... насколько я вижу, мое соединение с БД происходит оставаться навсегда.
Похоже на то, что в некоторых случаях возникает проблема, если итератор не закончит... я что-то упустил?