Блок «И наконец» в итераторах - PullRequest
8 голосов
/ 02 октября 2009

Есть ли какой-либо способ в блоке итератора C # предоставить блок кода, который будет выполняться, когда завершится foreach (или, естественно, будет разбит), скажем, для очистки ресурсов?

Лучшее, что я придумал, - это использование конструкции using, которая хороша, но для ее очистки нужен класс IDisposable. Например:

    public static IEnumerable<string> ReadLines(this Stream stream)
    {
        using (StreamReader rdr = new StreamReader(stream))
        {
            string txt = rdr.ReadLine();
            while (txt != null)
            {
                yield return txt;
                txt = rdr.ReadLine();
            }
            rdr.Close();
        }
    }

Ответы [ 2 ]

6 голосов
/ 02 октября 2009

try / finally работает нормально, если вызывающий абонент использует foreach или вручную вызывает Dispose на IEnumerator<T>. Если честно, если это нужно для очистки ресурсов, то оператор using, вероятно, будет лучшим способом сделать это - если вы используете ресурс, который нуждается в очистке, но не реализует IDisposable, это беспокойство само по себе:)

Существуют определенные ограничения на то, что вы можете делать в блоках итераторов, как объяснил в блоге Эрика Липперта , но в большинстве случаев все работает очень хорошо.

Вы можете найти мою статью о реализации блока итераторов интересной с точки зрения перевода finally.

0 голосов
/ 02 октября 2009

try/finally работает в этом случае.

public static IEnumerable<string> ReadLines(this Stream stream)
{
    StreamReader rdr = new StreamReader(stream);

    try
    {
        string txt = rdr.ReadLine();
        while (txt != null)
        {
            yield return txt;
            txt = rdr.ReadLine();
        }
        rdr.Close();
    }
    finally
    {
        rdr.Dispose();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...