Description
Background and motivation
Support IEnumerable<TSource>
/IAsyncEnumerable<TSource>
where TSource
is a ref struct
in LINQ methods where appropriate/possible to allow using these in such cases. E.g. there are cases where TSource
points to internal state of the enumerable source and one may want to prevent ToArray
/ToList
but would still like to support transformations like Select
or reductions like Count
or similar.
In general, all LINQ methods that do not involve storing/caching TSource
on the heap should annotated with allows ref struct
.
A concrete example of such a case is the .NET CSV library https://github.com/nietras/Sep consult README there for more background if necessary.
Currently, the lack of allows ref struct
prevents LINQ usage in such cases which either means no support or having to reinvent the wheel for this, which also means a less than ideal user experience since standard and known method cannot be used.
cc: @stephentoub
API Proposal
Example API changes, I do not have time to list all possible methods and this can be expanded over time incl. by others.
namespace System.Linq;
public static partial class Enumerable
{
public static int Count<TSource>(this IEnumerable<TSource> source)
#if NET9_0_OR_GREATER
where TSource : allows ref struct
#endif
}
public static partial class AsyncEnumerable
{
public static ValueTask<int> CountAsync<TSource>(
this IAsyncEnumerable<TSource> source,
CancellationToken cancellationToken = default)
#if NET9_0_OR_GREATER
where TSource : allows ref struct
#endif
}
Above support likely involves annotating support types like:
namespace System.Runtime.CompilerServices
[StructLayout(LayoutKind.Auto)]
public readonly struct ConfiguredCancelableAsyncEnumerable<T>
#if NET9_0_OR_GREATER
where T : allows ref struct
#endif
API Usage
No new API usage as such just expanded support via annotation.
Alternative Designs
None.
Risks
Given allows ref struct
defines a contract, forward compatibility may be a risk if one later decides to rewrite a given LINQ method in a way that is incompatible with this support. Risk should be very low and considered on a method by method basis.