-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add CollectionsMarshal #26867
Add CollectionsMarshal #26867
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace System.Runtime.InteropServices | ||
{ | ||
/// <summary> | ||
/// An unsafe class that provides a set of methods to access the underlying data representations of collections. | ||
/// </summary> | ||
public static class CollectionsMarshal | ||
{ | ||
/// <summary> | ||
/// Get a <see cref="Span{T}"/> view over a <see cref="List{T}"/>'s data. | ||
/// Items should not be added or removed from the <see cref="List{T}"/> while the <see cref="Span{T}"/> is in use. | ||
/// </summary> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: We should get in the habit of adding docs for parameters and return values (effectively all the xml fields that docs require). Something to consider going forward for new API additions (of course this applies to all future PRs and not just this one since we'd like to emphasize adding docs right in time and not accrue tech debt). For example, see the following (which has param name and return value docs): See the following for an example: cc @mairaw, @carlossanlop Is there a way for us to detect and highlight the missing gaps in docs right in PRs to make it easier/discover-able for contributors? |
||
public static Span<T> AsSpan<T>(List<T> list) => list.AsSpan(); | ||
/// <summary> | ||
/// Get a <see cref="ReadOnlySpan{T}"/> view over a <see cref="List{T}"/>'s data. | ||
/// Items should not be added or removed from the <see cref="List{T}"/> while the <see cref="ReadOnlySpan{T}"/> is in use. | ||
/// </summary> | ||
public static ReadOnlySpan<T> AsReadOnlySpan<T>(List<T> list) => list.AsSpan(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be "safe" and match what other mutating APIs do,
AsSpan()
needs to increment the version count.AsReadOnlySpan
does not have this requirement.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really needed to increment the version stamp? This is unsafe API. You have to know what you are doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way for users to ensure the version count is incremented without us doing it here?
The assumption is that, even if you are using this API for perf benefits, you still want to do the "correct" thing with regards to other usages (such as fulfilling the
IEnumerable<T>
contractList<T>
is currently exposing).Its a trivial operation to increment the version count once and makes it more correct. For the case where you aren't mutating you can just get the
ReadOnlySpan<T>
. If you really want to silently mutate and avoid the version increment, you can then useMemoryMarshal
to get a writeable span from theROSpan
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't mimic List's behaviour; it should increment the version count on each change rather than just obtaining the Span window (which then may not change anything). That can't be done; also it would defeat the purpose of the Api.
That said if you are using the Span and enumerating the List at the same time; would be an unfortunate approach as enumerating over the Span will be much faster (as it can remove the bounds checks and skip the enumerator creation) and you already have that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. The only downside is that it seems not ideal that users can't easily ensure "correct" versioning even if using the
Span<T>
APIs