C#/ Linq中方便的部分/流式枚举

时间:2015-03-09 15:38:33

标签: c# linq parsing stream

有时,在处理数组中的元素时,我发现将IEnumerable视为指定类型的只读流是有价值的。在诸如字节和文本操作之类的实例中,.Net在某种程度上覆盖了StreamReader和TextReader类,但是它们的接口并不像Linq那样干净。

我对IEnumerable的初步(和有缺陷的)理解是它以某种方式跟踪它在迭代中的位置,而不是在每次使用时开始新的迭代。

我在处理包含[4字节] [n字节]序列的IEnumerable时尝试使用它,其中'n'是前4个字节指定的长度,与此类似:

var len = BitConverter.ToInt32(input.Take(4), 0);
return input.Take(len);

这是不正确的,因为“输入”枚举没有通过调用Take(正如其设计所预期的)修改,留下前两个字节的双重表示和4个未读取。可以使用对“跳过”的调用,但会引起源的多次枚举,这是不需要的。 ToArray()调用是解决问题的拼凑解决方案,但在处理大块时可以通过多存储消耗过多的内存。我正在寻找一种执行此行为的替代方法,其中可枚举以与流类似的行为向前移动。

这种行为可以部分地使用枚举器上的扩展方法进行模拟,但是它依赖于用户管理或可能多次处理似乎有些笨拙,具体取决于实现。一个例子:

public static IEnumerable<T> Take<T>(this IEnumerator<T> enumerator, int count) {
    for(int i = 0; i < count; ++i) {
        if(!enumerator.MoveNext()) {
            using(enumerator) {
                break;
            }
        }
        yield return enumerator.Current;
    }
}
public static IEnumerable<T> AsEnumerable<T>(this IEnumerator<T> enumerator) {
    using(enumerator) {
        while(enumerator.MoveNext()) {
            yield return enumerator.Current;
        }
    }
}

总结一下,虽然我的问题暗示解决方案可能在于枚举机制,但我正在寻找一种干净的方式来处理任意类型的流,这些流也可以(干净地)处理具有依赖于或由先前元素声明的维度的格式。因为这是解析中的常见任务(例如,通常不使用原始字节或文本流,因为对泛型支持的请求很明显),我认为有一种相对简洁的方法来处理它? / p>

0 个答案:

没有答案