Select.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. namespace System.Linq
  9. {
  10. public static partial class AsyncEnumerable
  11. {
  12. public static IAsyncEnumerable<TResult> Select<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, TResult> selector)
  13. {
  14. if (source == null)
  15. throw new ArgumentNullException(nameof(source));
  16. if (selector == null)
  17. throw new ArgumentNullException(nameof(selector));
  18. return CreateEnumerable(
  19. () =>
  20. {
  21. var e = source.GetEnumerator();
  22. var current = default(TResult);
  23. var cts = new CancellationTokenDisposable();
  24. var d = Disposable.Create(cts, e);
  25. return CreateEnumerator(
  26. async ct =>
  27. {
  28. if (await e.MoveNext(cts.Token)
  29. .ConfigureAwait(false))
  30. {
  31. current = selector(e.Current);
  32. return true;
  33. }
  34. return false;
  35. },
  36. () => current,
  37. d.Dispose,
  38. e
  39. );
  40. });
  41. }
  42. public static IAsyncEnumerable<TResult> Select<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, TResult> selector)
  43. {
  44. if (source == null)
  45. throw new ArgumentNullException(nameof(source));
  46. if (selector == null)
  47. throw new ArgumentNullException(nameof(selector));
  48. return CreateEnumerable(
  49. () =>
  50. {
  51. var e = source.GetEnumerator();
  52. var current = default(TResult);
  53. var index = 0;
  54. var cts = new CancellationTokenDisposable();
  55. var d = Disposable.Create(cts, e);
  56. return CreateEnumerator(
  57. async ct =>
  58. {
  59. if (await e.MoveNext(cts.Token)
  60. .ConfigureAwait(false))
  61. {
  62. current = selector(e.Current, checked(index++));
  63. return true;
  64. }
  65. return false;
  66. },
  67. () => current,
  68. d.Dispose,
  69. e
  70. );
  71. });
  72. }
  73. }
  74. }