Skip to content

[API Proposal]: Annotate TSource with allows ref struct for both sync/async LINQ #111830

Closed as not planned
@nietras

Description

@nietras

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.Linq

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions