- Fluent operators (return
IAsyncEnumerable<T>) — no suffix (e.g.,Pipe,Choose,Batch) - Materializing operators (return
ValueTask<T>) —Asyncsuffix (e.g.,FoldAsync,ConsumeAsync,StartsWithAsync)
Each operator has sync and async delegate overloads sharing the same method name:
- Sync:
Func<T, TResult> - Async:
Func<T, CancellationToken, ValueTask<TResult>>—CancellationTokenis always the last delegate parameter
- Use
IsKnownEmpty()to short-circuit known empty sequences - Validate arguments in the public method, then delegate to a
staticlocalCoremethod - Use
[EnumeratorCancellation]on theCancellationTokenparameter in iterator methods - Use
source.WithCancellation(cancellationToken)inawait foreachloops - No
ConfigureAwait(false)— follow .NET runtime conventions
- Inherit from
AsyncEnumerableTests - Standard test methods:
InvalidInputs_Throws— verifyArgumentNullExceptionfor all null inputsEmptySequence— useAssertKnownEmpty()to verify empty sequence optimizationIsLazy— useBreakingSequence<T>andBreakingFunc.Of/OfAsyncto verify deferred execution
- Use
[Theory]with[MemberData(nameof(IsAsync))]to test sync and async delegate overloads - Use
AssertEqual(syncMoreLinqResult, asyncResult)to verify behavior matches MoreLINQ - Prefer
async (item, _) => ...over(x, _) => ValueTask.FromResult(...)
- Add new operator to
README.mdin alphabetical order - Approve new public API by copying
MoreAsyncLINQ.received.txttoMoreAsyncLINQ.verified.txt