Get first element from enumerable then iterate rest

I have an IEnumerable< Task< MyObject>> that effectively describes how to fetch a collection of items from cache. The MyObject element has an error message and a success object. I would like to do something like this:

List<MyObject> fetchAll(IEnumerable<Task<MyObject>> tasks)
{
    var (firstResponse, restOfEnumerable) = await tasks.DoSomethingToGetFirstResonseAndRestOfEnumerableAsync().ConfigureAwait(false);
    if(!firstResponse.IsSuccess)
    {
        return null;
    }

    List<MyObject> ret = new List<MyObject>(firstResponse.Result);
    ret.AddRange(await Task.WhenAll(restOfEnumerable).ConfigureAwait(false));
    return ret;
}

I know I could do this by calling ToList() on the enumerable and doing this

List<MyObject> fetchAll(List<Task<MyObject>> tasks)
    {
        var firstResponse = await tasks[0].ConfigureAwait(false);
        if (!firstResponse.IsSuccess)
        {
            return null;
        }
    
        List<MyObject> ret = new List<MyObject>(firstResponse.Result);
        ret.AddRange(await Task.WhenAll(tasks.Skip(1)).ConfigureAwait(false));
        return ret;
    }

but I'm trying to not iterate the IEnumerable fully just to test the first item.

I suppose I could also drop down and get the enumerator myself like this

List<MyObject> fetchAll(IEnumerable<Task<MyObject>> tasks)
{
    var ret = new List<MyObject>();
    using (var enumerator = tasks.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            var firstResult = await enumerator.Current.ConfigureAwait(false);
            if (!firstResponse.IsSuccess)
            {
                return null;
            }
            ret.Add(firstResponse.Result);
        }

        List<Task> restOfTasks = new List<Task>();
        while (enumerator.MoveNext())
        {
            restOfTasks.Add(enumerator.Current);
        }

        ret.AddRange(await Task.WhenAll(restOfTasks).ConfigureAwait(false));
    }
}

but I'm hoping there is something built in that I'm overlooking.


You can work with LINQ and use the method Enumerable.First to get the first element and Enumerable.Skip to skip the first element in an iteration.