-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[API Proposal]: List<T>.Create<TState>(int, TState, SpanAction<T, TState>)
#80756
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
List<T>.Create<TState>(int, TState, SpanAction<T, TState>)
List<T>.Create<TState>(int, TState, SpanAction<T, TState>)
Tagging subscribers to this area: @dotnet/area-system-collections Issue DetailsBackground and motivationAs of today, we do not have an API that would allow to safely initialize a While working on #80633 and investigating available ways to avoid using
However, it appears we do already have an example of similar use case that solves the same issue: API Proposalnamespace System.Collections.Generic;
public partial class List<T>
{
public static List<T> Create<TState>(int count, TState state, SpanAction<T, TState> action);
} API Usagepartial class SelectArrayIterator<TSource, TResult>
{
public List<TResult> ToList()
{
return List<TResult>.Create(_source.Length, this, (span, instance) =>
{
TSource[] source = instance._source;
Func<TSource, TResult> selector = instance._selector;
// Assert .Length equality between span and source to elide bounds check
for (int i = 0; i < span.Length; i++)
{
span[i] = _selector(source[i]);
}
}
}
} Alternative Designs
Risks
|
I don't see a point in this API, #55217 will make this fully possible with SetCount + AsSpan and reduced allocation scenarios in general target more advanced users. |
@MichalPetryka Generally speaking I agree, was simply concerned regarding the fate of your proposal due to some discussion in PR so submitted an alternative design just in case. I'm happy as long as your or any of the alternatives get into BCL 🙂 |
I'd be inclined to close this in favor #55217. We generally avoid adding new members to the |
Background and motivation
As of today, we do not have an API that would allow to safely initialize a
List<T>
's underlying buffer directly.While working on #80633 and investigating available ways to avoid using
for (...) { list.Add(element); }
inIListProvider<T>.ToList()
implementations, there seemed to be a couple of viable options:CollectionsMarshal.CreateList<T>(T[])
#80311ICollection<T>
stub that would wrap anIListProvider<T>
instance in order to get passed tonew List<T>(collection)
which would subsequently callCopyTo(...)
, achieving the goalHowever, it appears we do already have an example of similar use case that solves the same issue:
string.Create
.Re-using this pattern for
List<T>
would achieve safety (span cannot escape) and performance (no extra .Add() calls with state mutation, elided bounds check) at the same time without having to be hidden inCollectionsMarshal
class.API Proposal
API Usage
Alternative Designs
CollectionsMarshal.CreateList<T>(T[])
#80311Risks
string.Create
The text was updated successfully, but these errors were encountered: