在迭代器中“终于”阻塞

时间:2009-10-02 07:33:01

标签: c# iterator

在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 个答案:

答案 0 :(得分:6)

只要来电者使用try或在finally上手动拨打foreach

Dispose / IEnumerator<T>就可以正常工作。说实话,如果要清理资源,using语句可能是最好的方法 - 如果你使用的资源需要清理但是没有实现{{1这本身就是一个问题:)

对于你在迭代器块中可以做的事情有一些限制,如explained on Eric Lippert's blog,但在大多数情况下它都能很好地工作。

您可能会发现my article about iterator block implementationIDisposable的翻译方式感兴趣。

答案 1 :(得分:0)

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();
    }
}