流式传输一个 IEnumerable。

3

我有一个字符串列表,从文件中读取并进行过滤,这一切都是使用yield机制实现的,因此它是惰性的。然后我需要将其传递到一个需要TextReader的方法中。

这个方法有什么问题吗?它似乎可以工作,但想知道是否有遗漏。

public class EnumerableReader : TextReader
{
    private readonly IEnumerator<string> _enumerator;

    public EnumerableReader(IEnumerable<string> lines)
    {
        _enumerator = lines.GetEnumerator();
    }

    public override string ReadLine()
    {
        return _enumerator.MoveNext() ? _enumerator.Current : null;
    }

    protected override void Dispose(bool disposing)
    {
        _enumerator.Dispose();
        base.Dispose(disposing);
    }
}

当你完成时,不要忘记Dispose IEnumerator<string>。 - dtb
@dtb 我真的很好奇在这种情况下为什么主动释放 _enumerator 比在需要时让垃圾收集器处理更好?内存消耗? - Simon Belanger
2
@SimonBelanger:通常来说,因为你应该处理好你的IDisposables。在这种情况下,IEnumerator从文件中读取;你可能不想一直保持文件打开状态,直到GC最终关闭它,而是要有确定性地关闭它。 - dtb
如果我像更新示例那样添加Dispose会怎么样? - Schotime
1个回答

4
TextReader类公开了多个读取数据的方法。如果你将一个实例传递给某些外部代码,它可以使用任何方法,而不仅仅是ReadLine方法
最少需要重写的方法是Read方法Peek方法。如果你不重写它们,则两者始终返回-1,表示已到达结尾。包括ReadLine方法在内的所有其他方法都基于Read方法提供默认实现。你可以重写它们(例如,为了提高性能),但不是必需的。
MSDN上看到:
注意事项:
派生类必须至少实现PeekRead方法,以创建一个有用的TextReader实例。
因此,你的实现不能正常工作。

如果使用 Stream 的方法只调用 ReadLine(),会怎样呢? - Schotime
1
@Schotime 如果你已经知道这一点,那么你可能不应该使用 TextReader,而是使用自定义类型。 - svick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接