优化以下类型语句的正确方法是什么:
IEnumerable<T> sequence = BuildSequence(); // 'BuildSequence' makes some tough actions and uses 'yield return' // to form the resulting sequence.
现在,如果我愿意只采取一些第一个元素,我可以使用类似的东西:
sequence.Take(5);
因此,如果我的BuildSequence序列实际上包含数千个元素,我显然不希望构造所有元素,因为我只需要其中的5个.
LINQ是否优化了这种操作,或者我必须自己发明一些东西?
解决方法
迭代器块(yield return)为您处理此问题;迭代器块是一个流API;只有在迭代器(或Dispose()上)的每个MoveNext()调用期间才会发生工作.因为Take()也不读取整个流,所以保留了这种行为.
但请注意,某些操作需要在本地缓冲数据 – 最显着的是GroupBy和OrderBy;但只要你使用非缓冲操作,你就可以了.
例如:
static IEnumerable<int> ReadInts() { var rand = new Random(); while(true) yield return rand.Next(); } ... int count = ReadInts().Take(10).Count(); // 10 - it doesn't loop forever