C # IEnumerator / структура выхода потенциально плохая? - PullRequest
32 голосов
/ 29 апреля 2009

Справочная информация: у меня есть куча строк, которые я получаю из базы данных, и я хочу их вернуть. Традиционно это будет примерно так:

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

Похоже, что в некоторых случаях возникает проблема, если итератор не завершает работу ... я что-то упустил?

Ответы [ 11 ]

0 голосов
/ 29 апреля 2009

Не используйте выход здесь. Ваш образец в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...