Runtime: I suggest to add ReadOnlySequence constructor for ArraySegment

Created on 3 Apr 2018  Â·  6Comments  Â·  Source: dotnet/runtime

I suggest to add ReadOnlySequence constructor for ArraySegment.

Proposed API

    public readonly partial struct ReadOnlySequence<T>
    {
        /// <summary>
        /// Creates an instance of <see cref="ReadOnlySequence{T}"/> from the <see cref="ArraySegment{T}"/>.
        /// </summary>
        public ReadOnlySequence(ArraySegment<T> arraySegment);
    }

Details

Now we have three types for buffers: Array, ArraySegment, Memory. ReadOnlySequence have constructor for two of them, so it seems convenient to have constructor for ArraySegment too.

It is just sugar for public ReadOnlySequence(T[] array, int start, int length); constructor for ArraySegment.

api-needs-work area-System.Memory

Most helpful comment

@AlexRadch I don't understand why this proposal would be useful. ArraySegment<T> is implicitly convertible to ReadOnlyMemory<T>, so code like the following already works:

```c#
var segment = new ArraySegment(…);
var sequence = new ReadOnlySequence(segment);

@kamronbatman I think that's a separate request, since this one is about creating `ReadOnlySequence<T>` out of a single `ArraySegment<T>`. You might want to create a separate issue for that.

In case you didn't know, you can do what you want today, though it requires some extra code:

```c#
public static ReadOnlySequence<T> CreateSequence<T>(ArraySegment<T>[] segments)
{
    if (segments.Length == 0)
        return ReadOnlySequence<T>.Empty;

    var first = new BufferSegment<T>(segments[0]);
    var last = first;

    for (int i = 1; i < segments.Length; i++)
    {
        last = last.Append(segments[i]);
    }

    return new ReadOnlySequence<T>(first, 0, last, last.Memory.Length);
}

// Based on https://github.com/dotnet/aspnetcore/blob/ed5034e/src/Shared/Buffers.Testing/BufferSegment.cs
internal class BufferSegment<T> : ReadOnlySequenceSegment<T>
{
    public BufferSegment(Memory<T> memory) => Memory = memory;

    public BufferSegment<T> Append(Memory<T> memory)
    {
        var segment = new BufferSegment<T>(memory)
        {
            RunningIndex = RunningIndex + Memory.Length
        };
        Next = segment;
        return segment;
    }
}

I definitely wouldn't be against a convenience API for something like this.

All 6 comments

Can you please provide a scenario or code snippet where such a ctor would be useful? What motivates the need to add this API?

See example of "Rationale and Usage": https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md

The goal isn't to get a complete API list, but a good handle on how the new APIs would roughly look like and in what scenarios they are being used. Here is a good example.

It would be good to see a rationale for why we need such an API. What can't you do today that you can do if such an API was added?

It would be good to see a rationale for why we need such an API. What can't you do today that you can do if such an API was added?

It is just sugar for public ReadOnlySequence(T[] array, int start, int length); constructor for ArraySegment.

Now we have three types for buffers: Array, ArraySegment, Memory. ReadOnlySequence have constructor for two of them, so it seems convenient to have constructor for ArraySegment too.

I have a use case for this where I would like to get an ArraySegment<byte>[] from a socket, turn it into a ReadOnlySequence<byte> and use a SequenceReader<byte> to parse it.

@AlexRadch I don't understand why this proposal would be useful. ArraySegment<T> is implicitly convertible to ReadOnlyMemory<T>, so code like the following already works:

```c#
var segment = new ArraySegment(…);
var sequence = new ReadOnlySequence(segment);

@kamronbatman I think that's a separate request, since this one is about creating `ReadOnlySequence<T>` out of a single `ArraySegment<T>`. You might want to create a separate issue for that.

In case you didn't know, you can do what you want today, though it requires some extra code:

```c#
public static ReadOnlySequence<T> CreateSequence<T>(ArraySegment<T>[] segments)
{
    if (segments.Length == 0)
        return ReadOnlySequence<T>.Empty;

    var first = new BufferSegment<T>(segments[0]);
    var last = first;

    for (int i = 1; i < segments.Length; i++)
    {
        last = last.Append(segments[i]);
    }

    return new ReadOnlySequence<T>(first, 0, last, last.Memory.Length);
}

// Based on https://github.com/dotnet/aspnetcore/blob/ed5034e/src/Shared/Buffers.Testing/BufferSegment.cs
internal class BufferSegment<T> : ReadOnlySequenceSegment<T>
{
    public BufferSegment(Memory<T> memory) => Memory = memory;

    public BufferSegment<T> Append(Memory<T> memory)
    {
        var segment = new BufferSegment<T>(memory)
        {
            RunningIndex = RunningIndex + Memory.Length
        };
        Next = segment;
        return segment;
    }
}

I definitely wouldn't be against a convenience API for something like this.

I agree with @svick. The implicit cast for this should be sufficient. We don't need an arraysegment based ctor and I recommend closing this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jzabroski picture jzabroski  Â·  3Comments

Timovzl picture Timovzl  Â·  3Comments

iCodeWebApps picture iCodeWebApps  Â·  3Comments

omajid picture omajid  Â·  3Comments

chunseoklee picture chunseoklee  Â·  3Comments