-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Documentation for Span<T> #194
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
Changes from all commits
6e79b99
b79abaf
9437465
c412cbe
54e9abd
74ecbd3
f76aa7c
76dfc44
8091585
0bd08cd
9c693dc
316ec42
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 |
---|---|---|
|
@@ -21,8 +21,30 @@ | |
</Attribute> | ||
</Attributes> | ||
<Docs> | ||
<summary>To be added.</summary> | ||
<remarks>To be added.</remarks> | ||
<summary>Provides an enumerator for the elements of a <see cref="T:System.Span`1" />.</summary> | ||
<remarks> | ||
<format type="text/markdown">< of the C# language and the [For Each...Next](~/docs/visual-basic/language-reference/statements/for-each-next-statement.md) construct in Visual Basic hides the complexity of enumerators. Instead of directly manipulating the enumerator, using `foreach` or `For Each...Next` is recommended. | ||
|
||
Enumerators can be used to read the data in the <xref:System.Span%601>, but they cannot be used to modify it. | ||
|
||
Initially, the enumerator is positioned before the first element in the <xref:System.Span%601>. At this position, <xref:System.Span%601.Enumerator.Current> is undefined, so you must call <xref:System.Span%601.Enumerator.MoveNext%2A> to advance the enumerator to the first item in the <xref:System.Span%601> before reading the value of <xref:System.Span%601.Enumerator.Current>. | ||
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. At this position, Current throws an exception (it isn't undefined exactly). |
||
|
||
<xref:System.Span%601.Enumerator.Current> returns the same object until <xref:System.Span%601.Enumerator.MoveNext%2A> is called. <xref:System.Span%601.Enumerator.MoveNext%2A> sets <xref:System.Span%601.Enumerator.Current> to the next item in the <xref:System.Span%601>. | ||
|
||
If <xref:System.Span%601.Enumerator.MoveNext%2A> passes the end of the <xref:System.Span%601>, the enumerator is positioned after the last item in the <xref:System.Span%601>, and <xref:System.Span%601.Enumerator.MoveNext%2A> returns `false`. When the enumerator is at this position, subsequent calls to <xref:System.Span%601.Enumerator.MoveNext%2A> also return `false`. If the call to <xref:System.Span%601.Enumerator.MoveNext%2A> returns `false`, <xref:System.Span%601.Enumerator.Current> is undefined. You cannot set <xref:System.Span%601.Enumerator.Current> to the first item in the <xref:System.Span%601> again; you must create a new enumerator instance instead. | ||
|
||
The enumerator does not have exclusive access to the <xref:System.Span%601>; therefore, enumerating through a span is intrinsically not a thread-safe procedure. To guarantee thread safety during enumeration, you can lock the span during the entire enumeration. To allow the span to be accessed by multiple threads for reading and writing, you must implement your own synchronization. | ||
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.
@stephentoub, is this true? Couldn't the underlying array still be modified by another thread, or is the implication that the user needs some synchronization mechanism during enumeration and modification of the array? Also, how do we "lock" the span (it isn't a reference type). The following snippet has a race. To resolve it, we have to use a locking mechanism around both critical sections. static void Main(string[] args)
{
new Random(42).NextBytes(_array);
Span<byte> span = _array;
Thread thread = new Thread(delegate ()
{
ClearContents();
});
thread.Start();
EnumerateSpan(span);
}
private static readonly byte[] _array = new byte[5];
public static void ClearContents()
{
Thread.Sleep(20);
lock (_array)
{
Array.Clear(_array, 0, _array.Length);
}
}
public static void EnumerateSpan(Span<byte> span)
{
//lock (_array)
//{
foreach (byte element in span)
{
Console.WriteLine(element);
Thread.Sleep(10);
}
//}
} 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. First and foremost, there's no way to "lock the span". Presumably this was really just meant to say that you can use your own synchronization to enforce mutual exclusion. |
||
|
||
Unlike some other enumerator structures in .NET, <xref:System.Span%601.Enumerator>: | ||
|
||
- Does not implement the <xref:System.Collections.IEnumerator> or <xref:System.Collections.Generic.IEnumerator%601> interface. | ||
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. Might be worth mentioning that it's a |
||
|
||
- Does not include a `Reset` method, which sets the enumerator to its initial position before the first element in the span. | ||
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. Most enumerators provide Reset as it's part of the interface but throw or otherwise don't actually implement it. |
||
|
||
]]></format> | ||
</remarks> | ||
</Docs> | ||
<Members> | ||
<Member MemberName="Current"> | ||
|
@@ -40,9 +62,23 @@ | |
<ReturnType>T@</ReturnType> | ||
</ReturnValue> | ||
<Docs> | ||
<summary>To be added.</summary> | ||
<value>To be added.</value> | ||
<remarks>To be added.</remarks> | ||
<summary>Gets the item at the current position of the enumerator.</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. Maybe |
||
<value>The element in the <see cref="T:System.Span`1" /> at the current position of the enumerator.</value> | ||
<remarks> | ||
<format type="text/markdown"><![CDATA[ | ||
|
||
`Current` throws an <xref:System.IndexOutOfRangeException> under either of the following conditions: | ||
|
||
- Immediately after the enumertor is created, the enumerator is positioned before the first element in the span. <xref:System.Span%601.Enumerator.MoveNext%2A> must be called to advance the enumerator to the first element of the span before reading the value of `Current`. | ||
|
||
- The last call to <xref:System.Span%601.Enumerator.MoveNext%2A> returned `false`, which indicates the end of the span. | ||
|
||
`Current` returns the same object until <xref:System.Span%601.Enumerator.MoveNext%2A> is called. <xref:System.Span%601.Enumerator.MoveNext%2A> sets `Current` to the next item in the span. | ||
|
||
]]></format> | ||
</remarks> | ||
<exception cref="T:System.IndexOutOfRangeException"> | ||
The enumerator is positioned either before the first item or after the last item in the <see cref="System.Span`1" />.</exception> | ||
</Docs> | ||
</Member> | ||
<Member MemberName="MoveNext"> | ||
|
@@ -61,9 +97,17 @@ | |
</ReturnValue> | ||
<Parameters /> | ||
<Docs> | ||
<summary>To be added.</summary> | ||
<returns>To be added.</returns> | ||
<remarks>To be added.</remarks> | ||
<summary>Advances the enumerator to the next item of the <see cref="System.Span`1" />.</summary> | ||
<returns>`true` if the enumerator successfully advanced to the next item; `false` if the enumerator has passed the end of the span.</returns> | ||
<remarks> | ||
<format type="text/markdown"><![CDATA[ | ||
|
||
After an enumerator is created,it is positioned before the first element in the span, and the first call to `MoveNext` advances the enumerator to the first item in the span. | ||
|
||
If `MoveNext` passes the end of the span, the enumerator is positioned after the last item in the span, and `MoveNext` returns `false`. When the enumerator is at this position, subsequent calls to `MoveNext` also return `false`. | ||
|
||
]]></format> | ||
</remarks> | ||
</Docs> | ||
</Member> | ||
</Members> | ||
|
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.
It may be worth mentioning these two points:
Span<T>.Enumerator
does not implementIEnumarator<T>
.Span<T>.Enumerator
does not have aReset()
method.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.
@BillWagner, thanks. These are definitely worth mentioning.