Skip to content

Feature/ToAsyncEnumerable #326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -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
@@ -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)
3 changes: 3 additions & 0 deletions docs/CodeDoc/Atc/IndexExtended.md
Original file line number Diff line number Diff line change
@@ -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)
23 changes: 23 additions & 0 deletions docs/CodeDoc/Atc/System.Collections.Generic.md
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/Atc.XUnit/Atc.XUnit.csproj
Original file line number Diff line number Diff line change
@@ -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>
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
@@ -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),
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);
}
}