0

I wish to obtain the original value a Span represents. Take the following code for example, how would I, in DoWork, gain access to the original byte array without creating a copy of it?

static void Main()
{
    var data = new byte[0x100];
    DoWork(new Span<byte>(data));
}

private void DoWork(Span<byte> Data)
{
    //var data = Data.ToArray(); Unsuitable; creates a copy
    //var data = (byte[])Data; Unsuitable; doesn't work
    //MemoryMarshal. Something in here may work, but unsure
    //MemoryExtensions. Something in here may work, but unsure
}

I found 2 static classes with helper methods (shown above) that may help, but I am unsure as to what is the best way to do this without making things slower than just making a copy.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 1
    A span is a window on the original value, think of it as a pointer to that byte. Because you have the span, you have a reference to the actual value. `Data[i]` will give you the reference to the index specified or iterate over the span to see all the references in the window. – Kieran Devlin Mar 13 '19 at 16:14
  • 3
    The whole point of `Span` is to give you an abstracted view of the original data. It would be a layer violation for `DoWork` to 1) *assume* `Data` was backed by a `byte[]` (and not unmanaged memory, for example) and 2) reach out through the encapsulation to get at that `byte[]`. You should (re)-write code inside `DoWork` to use the `Span` so you have no need for getting "the original byte array" in the first place. If you *do* need it, then don't pass a `Span` -- pass the array! `Span` gains you nothing while other code is still working only on arrays anyway. – Jeroen Mostert Mar 13 '19 at 16:15
  • Technically this is impossible. A span contains a pointer, which may point into the middle of the byte array. You can't take that pointer and find the beginning of the byte array again. Likewise you can't take that pointer and construct a new array starting at that pointer, without copying. – canton7 Mar 13 '19 at 16:19
  • There's no copy involved. You *are* looking at the original value through that Span. Why not just use the Span as is? Why create an array from it? – Panagiotis Kanavos Mar 13 '19 at 16:26
  • Thanks everyone for the clarification. – Andr-Finsky Mar 13 '19 at 18:45
  • Check that question, could clear and explain more stuff for you https://stackoverflow.com/a/75362556/3351489 – CorrM Feb 07 '23 at 00:26

1 Answers1

0

According to the Span Document:

Because it is a stack-only type, Span is unsuitable for many scenarios that require storing references to buffers on the heap. This is true, for example, of routines that make asynchrous method calls. For such scenarios, you can use the complimentary System.Memory and System.ReadOnlyMemory types.

So maybe to your need, you don't have to use a Span:

static void Main()
{
    var data = new byte[0x100];
    DoWork(data);
}
private void DoWork(byte[] data)
{
    // data array is by reference.
}