Repeat.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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.Collections.Generic;
  5. using System.Threading.Tasks;
  6. namespace System.Linq
  7. {
  8. public static partial class AsyncEnumerable
  9. {
  10. public static IAsyncEnumerable<TResult> Repeat<TResult>(TResult element, int count)
  11. {
  12. if (count < 0)
  13. throw new ArgumentOutOfRangeException(nameof(count));
  14. return Enumerable.Repeat(element, count).ToAsyncEnumerable();
  15. }
  16. private sealed class RepeatAsyncIterator<TResult> : AsyncIterator<TResult>
  17. {
  18. private readonly TResult element;
  19. private readonly int count;
  20. private int remaining;
  21. public RepeatAsyncIterator(TResult element, int count)
  22. {
  23. this.element = element;
  24. this.count = count;
  25. }
  26. public override AsyncIterator<TResult> Clone() => new RepeatAsyncIterator<TResult>(element, count);
  27. protected override async Task<bool> MoveNextCore()
  28. {
  29. switch (state)
  30. {
  31. case AsyncIteratorState.Allocated:
  32. remaining = count;
  33. if (remaining > 0)
  34. {
  35. current = element;
  36. }
  37. state = AsyncIteratorState.Iterating;
  38. goto case AsyncIteratorState.Iterating;
  39. case AsyncIteratorState.Iterating:
  40. if (remaining-- != 0)
  41. {
  42. return true;
  43. }
  44. break;
  45. }
  46. await DisposeAsync().ConfigureAwait(false);
  47. return false;
  48. }
  49. }
  50. }
  51. }