Contains.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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;
  6. using System.Threading.Tasks;
  7. namespace System.Linq
  8. {
  9. public static partial class AsyncEnumerable
  10. {
  11. public static Task<bool> ContainsAsync<TSource>(this IAsyncEnumerable<TSource> source, TSource value, CancellationToken cancellationToken = default)
  12. {
  13. if (source == null)
  14. throw Error.ArgumentNull(nameof(source));
  15. if (source is ICollection<TSource> collection)
  16. {
  17. return Task.FromResult(collection.Contains(value));
  18. }
  19. return ContainsCore(source, value, comparer: null, cancellationToken);
  20. }
  21. public static Task<bool> ContainsAsync<TSource>(this IAsyncEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer, CancellationToken cancellationToken = default)
  22. {
  23. if (source == null)
  24. throw Error.ArgumentNull(nameof(source));
  25. return ContainsCore(source, value, comparer, cancellationToken);
  26. }
  27. private static async Task<bool> ContainsCore<TSource>(IAsyncEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer, CancellationToken cancellationToken)
  28. {
  29. #if CSHARP8 && AETOR_HAS_CT // CS0656 Missing compiler required member 'System.Collections.Generic.IAsyncEnumerable`1.GetAsyncEnumerator'
  30. //
  31. // See https://github.com/dotnet/corefx/pull/25097 for the optimization here.
  32. //
  33. if (comparer == null)
  34. {
  35. await foreach (TSource item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
  36. {
  37. if (EqualityComparer<TSource>.Default.Equals(item, value))
  38. {
  39. return true;
  40. }
  41. }
  42. }
  43. else
  44. {
  45. await foreach (TSource item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
  46. {
  47. if (comparer.Equals(item, value))
  48. {
  49. return true;
  50. }
  51. }
  52. }
  53. #else
  54. var e = source.GetAsyncEnumerator(cancellationToken);
  55. try
  56. {
  57. //
  58. // See https://github.com/dotnet/corefx/pull/25097 for the optimization here.
  59. //
  60. if (comparer == null)
  61. {
  62. while (await e.MoveNextAsync().ConfigureAwait(false))
  63. {
  64. if (EqualityComparer<TSource>.Default.Equals(e.Current, value))
  65. {
  66. return true;
  67. }
  68. }
  69. }
  70. else
  71. {
  72. while (await e.MoveNextAsync().ConfigureAwait(false))
  73. {
  74. if (comparer.Equals(e.Current, value))
  75. {
  76. return true;
  77. }
  78. }
  79. }
  80. }
  81. finally
  82. {
  83. await e.DisposeAsync().ConfigureAwait(false);
  84. }
  85. #endif
  86. return false;
  87. }
  88. }
  89. }