-
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
Add "slicing" APIs to ArraySegment<T> #18007
Comments
Does it make a copy? |
@omariom, yes. this is why I made it an explicit cast. Possibly it should be removed completely. |
The nice about a conversion operatator is that the compiler will give you an error message like:
Now, one could also argue that this is the problem if people just apply the cast without realizing that there is performance/memory penalty for doing so. public T[] CreateArray(); I think we should call it Other than that, the proposals look good to me. |
Good candidat for implicit operator is conversation to |
Changed CreateArray to ToArray |
Here are all of public void CopyTo(T[] array);
public void CopyTo(T[] array, int arrayIndex);
public void CopyTo(int index, T[] array, int arrayIndex, int count); Should In other words:
|
Interestingly, public void CopyTo(T[] destination);
public void CopyTo(T[] destination, int destinationIndex);
public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length); Whereas |
I like |
updated CopyTo to use "destination" |
What is the point of adding |
Are we going to add array segment to more APIs as well. Nothing takes array segment except for the web socket APIs |
@davidfowl, yes. I think we should/must. |
@KrzysztofCwalina is it ready for API review? |
We should remove the explicit operator as it seems weird. And The indexer needs to perform a range check; it doesn't have to perform a null check because the range check can just use the fields (offset and count). The only case to observe a null reference is when the Also, namespace System
{
partial struct ArraySegment<T>
{
public T this[int index] { get; set; }
public static implicit operator ArraySegment<T>(T[] array);
public T[] ToArray();
public int Length { get; }
public ArraySegment<T> Slice(int index, int count);
public ArraySegment<T> Slice(int index);
public void CopyTo(T[] destination);
public void CopyTo(T[] destination, int destinationIndex);
public void CopyTo(T[] destination, int destinationIndex, int count);
public void CopyTo(ArraySegment<T> destination);
public static ArraySegment<T> Empty { get; }
}
} |
The low-level APIs which already live in coreclr repo ('corlib') need to be done first there. All APIs should have tests and reference assemblies in corefx repo - it is tricky and not best documented process at this moment. |
@karelz I made two simple PRs in corefx, but have issues with changing config files. Can you help me? dotnet/corefx#13975 and dotnet/corefx#13976 |
@AlexRadch the more reason to not attack coreclr+corefx changes which are more tricky. I hope that @Priya91 and @ianhays will be able to help you with the two above. I myself still lack the experience in making those changes to be able to provide useful advice. |
@AlexRadch From your PR, seems like you're not adding the APIs proposed in this issue. I left feedback on one of your PRs. Please keep the conversation on related issues. |
What difference between array slices, array spans and array segments ? I am confused :( |
@Priya91 @AlexRadch is there PR for this issue? If yes, it should be linked. Slices and spans are part of the new |
I'm not aware of any.. |
@karelz Why add new methods to old API? May be better to mark |
@AlexRadch @terrajobst Regarding the proposal you have above namespace System
{
partial struct ArraySegment<T>
{
public T this[int index] { get; set; }
public static implicit operator ArraySegment<T>(T[] array);
public T[] ToArray();
public int Length { get; }
public ArraySegment<T> Slice(int index, int count);
public ArraySegment<T> Slice(int index);
public void CopyTo(T[] destination);
public void CopyTo(T[] destination, int destinationIndex);
public void CopyTo(T[] destination, int destinationIndex, int count);
public void CopyTo(ArraySegment<T> destination);
public static ArraySegment<T> Empty { get; }
}
}
|
New proposed is namespace System
{
public struct ArraySegment<T> : IList<T>, IReadOnlyList<T>, IEquatable<ArraySegment<T>>
{
public ref T this[int index] { get; }
public static implicit operator ArraySegment<T>(T[] array);
public T[] ToArray();
public int Length { get; }
public ArraySegment<T> Slice(int index, int count);
public ArraySegment<T> Slice(int index);
public void CopyTo(Span<T> destination);
public static ArraySegment<T> Empty { get; }
}
} |
@karelz Sorry, I just noticed this has already been marked api-approved... was the above spec the final decision, or can this be reviewed again? |
There is always option to change ... changing APIs before we ship them in major release is "doable".
|
re # 1: Span's indexer is now by ref (which was decided at an API review meeting), so we already approved this new pattern. There are trade offs here, but long term the wins are large, so I think we should go with it. |
Thanks @KrzysztofCwalina! That makes sense. @AlexRadch your questions [1] and [2] are now answered -- we won't use |
@karelz ok about [1] and [2] But if we will remove So I suggest do not add It can be easy coded as @KrzysztofCwalina What do you think? |
I could live without that overload |
We just talked about it and concluded we should indeed remove this overload: public void CopyTo(T[] destination, int destinationIndex, int count); We should leave the other |
@AlexRadch thanks for pointing it out. The API proposal in the top post is now updated. Feel free to implement it as defined in the top post. |
@karelz I found 2 issues about Empty
|
Let's track |
@karelz I created separate issue dotnet/corefx#14502 |
No activity/response for 1.5 months, unassigning the issue - it is "up for grabs" again, available for anyone to pick it up and finish it. |
@KrzysztofCwalina actually wanted this one to happen in 2.0 - he said he will do it himself if no one picks it up ... |
@karelz Curious, when does 2.0 come out? |
@jamesqo check the milestone description: https://github.com/dotnet/corefx/milestones |
@jamesqo if you want to pick up this issue, it would be appreciated ;-) |
@karelz Sure, one thing though. It seems like from the previous discussion @KrzysztofCwalina decided in favor of having a |
@karelz, @terrajobst made a post further down here that had the latest proposed API at the time, so I think the current proposal looks like namespace System
{
partial struct ArraySegment<T>
{
public ref T this[int index] { get; }
public static implicit operator ArraySegment<T>(T[] array);
public T[] ToArray();
public ArraySegment<T> Slice(int index, int count);
public ArraySegment<T> Slice(int index);
public void CopyTo(T[] destination);
public void CopyTo(T[] destination, int destinationIndex);
public void CopyTo(ArraySegment<T> destination);
public static ArraySegment<T> Empty { get; }
}
} Correct? |
@KrzysztofCwalina By the way, why are we having |
The point was to make it easier to switch from array, span, etc. to arraysegment and vice versa. But I agree there is a negative aspect of the addition. |
@KrzysztofCwalina OK. I have pushed it out of the proposal for now, then; it can be added later if you change your mind. I have a question that came up while I was working on the implementation: should |
@karelz, regarding whether |
@jamesqo I don't have much experience with @KrzysztofCwalina you said you really want this to happen in .NET Core 2.0 - can you please help drive it (incl. answering @jamesqo's questions), if it is still true? Thanks! (sorry I don't have enough expertise on this type + not enough bandwidth lately :() |
@karelz below are currently implemented in coreclr but not exposed in corefx. Ideally we would have tests and expose them. Some of this was implemented by @jamesqo, some by another contributor who has left. public struct ArraySegment<T> : ICollection<T>, IEnumerable, IEnumerable<T>, IList<T>, IReadOnlyCollection<T>, IReadOnlyList<T> {
public static ArraySegment<T> Empty { get; }
public T this[int index] { get; set; }
public void CopyTo(ArraySegment<T> destination);
public void CopyTo(T[] destination);
public void CopyTo(T[] destination, int destinationIndex);
public ArraySegment<T>.Enumerator GetEnumerator();
public static implicit operator ArraySegment<T> (T[] array);
public ArraySegment<T> Slice(int index);
public ArraySegment<T> Slice(int index, int count);
public T[] ToArray();
public struct Enumerator : IDisposable, IEnumerator, IEnumerator<T> {
public T Current { get; }
object System.Collections.IEnumerator.Current { get; }
public void Dispose();
public bool MoveNext();
void System.Collections.IEnumerator.Reset();
}
} |
/cc @stephentoub fyi |
They're being exposed here: dotnet/corefx#17033 |
ArraySegment could be much more useful if it had the following additional APIs. I propose that we add these members to ArraySegment:
The text was updated successfully, but these errors were encountered: