有时,在处理数组中的元素时,我发现将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>