Closed KrzysztofCwalina closed 4 years ago
@karelz Sure, one thing though. It seems like from the previous discussion @KrzysztofCwalina decided in favor of having a ref T
indexer, but the proposal was never updated?
@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 ArraySegment<T>.Length
when we already have ArraySegment<T>.Count
? Is that required for the compiler to recognize ArraySegment
as a type that can be sliced when spans get language support? It seems really weird/confusing to have two properties that do the same thing.
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 Slice
accept negative indices? If you do new ArraySegment<T>(new T[1], 1, 0).Slice(-1)
should you get an ArraySegment
that contains the first element or should an exception be thrown?
@karelz, regarding whether ArraySegment<T>
should implement IEquatable
or not, here is an issue that would have been avoided entirely if it was IEquatable
. To see if 2 ArraySegments are equal, xUnit's default comparer checks first if they are IEquatable
. Since they aren't, eventually it falls back to treating them like collections and calling GetEnumerator
, which throws for a default ArraySegment<T>
. I think there is value in implementing the interface.
@jamesqo I don't have much experience with IEquatable
interface. What you say makes sense, but I let btter experts to make the call. It might be easier to move it into separate issue as it needs API approval.
@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: https://github.com/dotnet/corefx/pull/17033
ArraySegment could be much more useful if it had the following additional APIs. I propose that we add these members to ArraySegment: