我有一个枚举,其中包含来自服务调用的响应,这些响应逐渐出现。
ToList
,因为那样会阻塞,直到收到所有响应,而不是在它们出现时列出它们。 如何获取可枚举中的第一个元素并返回可枚举的延续?出现编译错误时,我无法使用迭代器方法:
迭代器不能具有ref,in或out参数。
我已经尝试过此代码:
public IEnumerable<object> GetFirstAndReturn(IEnumerable<object> enumerable, out object first)
{
first = enumerable.Take(1).FirstOrDefault();
return enumerable.Skip(1); // Second interation - unexceptable
}
// This one has a compilation error: Iterators cannot have ref, in or out parameters
public IEnumerable<object> GetFirstAndReturn2(IEnumerable<object> enumerable, out object first)
{
var enumerator = enumerable.GetEnumerator();
first = enumerator.Current;
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
代替使用out
参数,可以使用ValueTuple<T1, T2>
(从C#7.0起,已记录在here中)返回两个元素:IEnumerable<T>
的第一项,其余的作为另一个IEnumerable<T>
。
using System.Linq;
class Program {
static void Main(string[] args) {
(int first, IEnumerable<int> remainder) = GetFirstAndRemainder(Enumerable.Range(1, 5));
// first = 1
// remainder yields (2, 3, 4, 5)
}
// Returns the first item and the remainders as an IEnumerable
static (T, IEnumerable<T>) GetFirstAndRemainder<T>(IEnumerable<T> sequence) {
var enumerator = sequence.GetEnumerator();
enumerator.MoveNext();
return (enumerator.Current, enumerator.AsEnumerable());
}
}
您还需要使用扩展方法将IEnumerator
转换为IEnumerable
:
static class Extensions {
public static IEnumerable<T> AsEnumerable<T>(this IEnumerator<T> enumerator) {
while (enumerator.MoveNext()) {
yield return enumerator.Current;
}
}
}
请注意,根据您的要求,即使remainder
的类型为IEnumerable<T>
,对其进行一次迭代也会耗尽它。