Skip to content

Commit

Permalink
Merge pull request #326 from atc-net/feature/ToAsyncEnumerable
Browse files Browse the repository at this point in the history
Feature/ToAsyncEnumerable
  • Loading branch information
davidkallesen authored Jul 24, 2024
2 parents fadc252 + 61d75ee commit 6cf33cf
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
<ItemGroup Label="Code Analyzers">
<PackageReference Include="AsyncFixer" Version="1.6.0" PrivateAssets="All" />
<PackageReference Include="Asyncify" Version="0.9.7" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.160" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.161" PrivateAssets="All" />
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.29.0.95321" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.30.0.95878" PrivateAssets="All" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions docs/CodeDoc/Atc/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@

## [System.Collections.Generic](System.Collections.Generic.md)

- [EnumerableExtensions](System.Collections.Generic.md#enumerableextensions)
- [ReadOnlyListExtensions](System.Collections.Generic.md#readonlylistextensions)

## [System.ComponentModel.DataAnnotations](System.ComponentModel.DataAnnotations.md)
Expand Down
3 changes: 3 additions & 0 deletions docs/CodeDoc/Atc/IndexExtended.md
Original file line number Diff line number Diff line change
Expand Up @@ -5284,6 +5284,9 @@

## [System.Collections.Generic](System.Collections.Generic.md)

- [EnumerableExtensions](System.Collections.Generic.md#enumerableextensions)
- Static Methods
- ToAsyncEnumerable(this IEnumerable&lt;T&gt; source, CancellationToken cancellationToken = null)
- [ReadOnlyListExtensions](System.Collections.Generic.md#readonlylistextensions)
- Static Methods
- GetPowerSet(this IReadOnlyList&lt;T&gt; list)
Expand Down
23 changes: 23 additions & 0 deletions docs/CodeDoc/Atc/System.Collections.Generic.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@

<br />

## EnumerableExtensions
Provides extension methods for asynchronous enumeration of collections.

>```csharp
>public static class EnumerableExtensions
>```
### Static Methods
#### ToAsyncEnumerable
>```csharp
>IAsyncEnumerable<T> ToAsyncEnumerable(this IEnumerable<T> source, CancellationToken cancellationToken = null)
>```
><b>Summary:</b> Converts an `System.Collections.Generic.IEnumerable`1` to an `System.Collections.Generic.IAsyncEnumerable`1`.
>
><b>Parameters:</b><br>
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`source`&nbsp;&nbsp;-&nbsp;&nbsp;The source sequence to convert.<br />
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cancellationToken`&nbsp;&nbsp;-&nbsp;&nbsp;A to observe while waiting for the asynchronous operation to complete.<br />
>
><b>Returns:</b> An `System.Collections.Generic.IAsyncEnumerable`1` that contains the elements from the input sequence.
<br />
## ReadOnlyListExtensions
>```csharp
Expand Down
2 changes: 1 addition & 1 deletion src/Atc.XUnit/Atc.XUnit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="EPPlus" Version="7.2.1" />
<PackageReference Include="EPPlus" Version="7.2.2" />
<PackageReference Include="ICSharpCode.Decompiler" Version="8.2.0.7535" />
<PackageReference Include="Mono.Reflection" Version="2.0.0">
<NoWarn>NU1701</NoWarn>
Expand Down
44 changes: 44 additions & 0 deletions src/Atc/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// ReSharper disable once CheckNamespace
namespace System.Collections.Generic;

/// <summary>
/// Provides extension methods for asynchronous enumeration of collections.
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// Converts an <see cref="IEnumerable{T}"/> to an <see cref="IAsyncEnumerable{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the elements in the source sequence.</typeparam>
/// <param name="source">The source sequence to convert.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the asynchronous operation to complete.</param>
/// <returns>An <see cref="IAsyncEnumerable{T}"/> that contains the elements from the input sequence.</returns>
/// <exception cref="ArgumentNullException">Thrown when the source sequence is null.</exception>
[SuppressMessage("Design", "MA0050:Validate arguments correctly in iterator methods", Justification = "OK - False/Positive")]
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(
this IEnumerable<T> source,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}

await foreach (var item in IterateAsync(source, cancellationToken).ConfigureAwait(false))
{
yield return item;
}
}

private static async IAsyncEnumerable<T> IterateAsync<T>(
IEnumerable<T> source,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
foreach (var item in source)
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
await Task.Yield();
}
}
}
1 change: 1 addition & 0 deletions test/Atc.Tests/CodeComplianceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class CodeComplianceTests
typeof(StackTraceHelper),

// UnitTests are made, but CodeCompliance test cannot detect this
typeof(EnumerableExtensions),
typeof(EnumAtcExtensions),
typeof(DynamicJson),
typeof(EnumHelper),
Expand Down
22 changes: 22 additions & 0 deletions test/Atc.Tests/Extensions/EnumerableExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ReSharper disable PossibleMultipleEnumeration
namespace Atc.Tests.Extensions;

public class EnumerableExtensionsTests
{
[Fact]
public async Task ToAsyncEnumerable()
{
// Arrange
var source = Enumerable.Range(1, 5);

// Act
var result = new List<int>();
await foreach (var item in source.ToAsyncEnumerable())
{
result.Add(item);
}

// Assert
Assert.Equal(source, result);
}
}

0 comments on commit 6cf33cf

Please sign in to comment.