|
@@ -15,171 +15,169 @@ namespace System.Linq
|
|
|
if (source == null)
|
|
|
throw Error.ArgumentNull(nameof(source));
|
|
|
|
|
|
- return SingleCore(source, cancellationToken);
|
|
|
- }
|
|
|
-
|
|
|
- public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate, CancellationToken cancellationToken = default)
|
|
|
- {
|
|
|
- if (source == null)
|
|
|
- throw Error.ArgumentNull(nameof(source));
|
|
|
- if (predicate == null)
|
|
|
- throw Error.ArgumentNull(nameof(predicate));
|
|
|
-
|
|
|
- return SingleCore(source, predicate, cancellationToken);
|
|
|
- }
|
|
|
-
|
|
|
- public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<bool>> predicate, CancellationToken cancellationToken = default)
|
|
|
- {
|
|
|
- if (source == null)
|
|
|
- throw Error.ArgumentNull(nameof(source));
|
|
|
- if (predicate == null)
|
|
|
- throw Error.ArgumentNull(nameof(predicate));
|
|
|
-
|
|
|
- return SingleCore(source, predicate, cancellationToken);
|
|
|
- }
|
|
|
-
|
|
|
-#if !NO_DEEP_CANCELLATION
|
|
|
- public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<bool>> predicate, CancellationToken cancellationToken = default)
|
|
|
- {
|
|
|
- if (source == null)
|
|
|
- throw Error.ArgumentNull(nameof(source));
|
|
|
- if (predicate == null)
|
|
|
- throw Error.ArgumentNull(nameof(predicate));
|
|
|
+ return Core();
|
|
|
|
|
|
- return SingleCore(source, predicate, cancellationToken);
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- private static async Task<TSource> SingleCore<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
|
|
|
- {
|
|
|
- if (source is IList<TSource> list)
|
|
|
+ async Task<TSource> Core()
|
|
|
{
|
|
|
- switch (list.Count)
|
|
|
+ if (source is IList<TSource> list)
|
|
|
{
|
|
|
- case 0: throw Error.NoElements();
|
|
|
- case 1: return list[0];
|
|
|
- }
|
|
|
+ switch (list.Count)
|
|
|
+ {
|
|
|
+ case 0: throw Error.NoElements();
|
|
|
+ case 1: return list[0];
|
|
|
+ }
|
|
|
|
|
|
- throw Error.MoreThanOneElement();
|
|
|
- }
|
|
|
+ throw Error.MoreThanOneElement();
|
|
|
+ }
|
|
|
|
|
|
- var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
- try
|
|
|
- {
|
|
|
- if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ try
|
|
|
{
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
|
|
|
- var result = e.Current;
|
|
|
- if (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ var result = e.Current;
|
|
|
+ if (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.MoreThanOneElement();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ finally
|
|
|
{
|
|
|
- throw Error.MoreThanOneElement();
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
}
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- await e.DisposeAsync().ConfigureAwait(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static async Task<TSource> SingleCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate, CancellationToken cancellationToken)
|
|
|
+ public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate, CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
- var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+ if (source == null)
|
|
|
+ throw Error.ArgumentNull(nameof(source));
|
|
|
+ if (predicate == null)
|
|
|
+ throw Error.ArgumentNull(nameof(predicate));
|
|
|
|
|
|
- try
|
|
|
+ return Core();
|
|
|
+
|
|
|
+ async Task<TSource> Core()
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
- {
|
|
|
- var result = e.Current;
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
- if (predicate(result))
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ var result = e.Current;
|
|
|
+
|
|
|
+ if (predicate(result))
|
|
|
{
|
|
|
- if (predicate(e.Current))
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- throw Error.MoreThanOneElement();
|
|
|
+ if (predicate(e.Current))
|
|
|
+ {
|
|
|
+ throw Error.MoreThanOneElement();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static async Task<TSource> SingleCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<bool>> predicate, CancellationToken cancellationToken)
|
|
|
+ public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<bool>> predicate, CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
- var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+ if (source == null)
|
|
|
+ throw Error.ArgumentNull(nameof(source));
|
|
|
+ if (predicate == null)
|
|
|
+ throw Error.ArgumentNull(nameof(predicate));
|
|
|
|
|
|
- try
|
|
|
+ return Core();
|
|
|
+
|
|
|
+ async Task<TSource> Core()
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
- {
|
|
|
- var result = e.Current;
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
- if (await predicate(result).ConfigureAwait(false))
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ var result = e.Current;
|
|
|
+
|
|
|
+ if (await predicate(result).ConfigureAwait(false))
|
|
|
{
|
|
|
- if (await predicate(e.Current).ConfigureAwait(false))
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- throw Error.MoreThanOneElement();
|
|
|
+ if (await predicate(e.Current).ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.MoreThanOneElement();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#if !NO_DEEP_CANCELLATION
|
|
|
- private static async Task<TSource> SingleCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<bool>> predicate, CancellationToken cancellationToken)
|
|
|
+ public static Task<TSource> SingleAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<bool>> predicate, CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
- var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+ if (source == null)
|
|
|
+ throw Error.ArgumentNull(nameof(source));
|
|
|
+ if (predicate == null)
|
|
|
+ throw Error.ArgumentNull(nameof(predicate));
|
|
|
+
|
|
|
+ return Core();
|
|
|
|
|
|
- try
|
|
|
+ async Task<TSource> Core()
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
- {
|
|
|
- var result = e.Current;
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
- if (await predicate(result, cancellationToken).ConfigureAwait(false))
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ var result = e.Current;
|
|
|
+
|
|
|
+ if (await predicate(result, cancellationToken).ConfigureAwait(false))
|
|
|
{
|
|
|
- if (await predicate(e.Current, cancellationToken).ConfigureAwait(false))
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- throw Error.MoreThanOneElement();
|
|
|
+ if (await predicate(e.Current, cancellationToken).ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.MoreThanOneElement();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
#endif
|