背景:我有一堆从数据库中获取的字符串,我想返回它们。传统上,它会是这样的:
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 似乎没有提到这一点),它显然是一个懒惰的评估器,它保持填充器的状态,期待有人问下一个值,然后只运行它直到它返回下一个值。
在大多数情况下这似乎很好,但是使用数据库调用,这听起来有点冒险。作为一个有点人为的例子,如果有人从我从数据库调用中填充的 IEnumerable 中请求一个 IEnumerable,通过它的一半,然后陷入循环......据我所知,我的数据库连接正在进行永远保持开放。
如果迭代器没有完成,在某些情况下听起来像是自找麻烦……我错过了什么吗?