// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace System.Linq { public static partial class AsyncEnumerable { /// /// Returns an empty async-enumerable sequence. /// /// The type used for the type parameter of the resulting sequence. /// An async-enumerable sequence with no elements. public static IAsyncEnumerable Empty() => EmptyAsyncIterator.Instance; internal sealed class EmptyAsyncIterator : IAsyncPartition, IAsyncEnumerator { public static readonly EmptyAsyncIterator Instance = new EmptyAsyncIterator(); public TValue Current => default!; public ValueTask GetCountAsync(bool onlyIfCheap, CancellationToken cancellationToken) => new ValueTask(0); public IAsyncPartition Skip(int count) => this; public IAsyncPartition Take(int count) => this; public ValueTask ToArrayAsync(CancellationToken cancellationToken) => new ValueTask( #if NO_ARRAY_EMPTY EmptyArray.Value #else Array.Empty() #endif ); public ValueTask> ToListAsync(CancellationToken cancellationToken) => new ValueTask>(new List()); public ValueTask> TryGetElementAtAsync(int index, CancellationToken cancellationToken) => new ValueTask>(new Maybe()); public ValueTask> TryGetFirstAsync(CancellationToken cancellationToken) => new ValueTask>(new Maybe()); public ValueTask> TryGetLastAsync(CancellationToken cancellationToken) => new ValueTask>(new Maybe()); public ValueTask MoveNextAsync() => new ValueTask(false); public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // NB: [LDM-2018-11-28] Equivalent to async iterator behavior. return this; } public ValueTask DisposeAsync() => default; } } }