Search code examples
c#.net-standard-2.0.net-4.6.net-core-2.1

Can I get a pointer to a Span?


I have a (ReadOnly)Span<byte> from which I want to decode a string.

Only in .NET Core 2.1 I have the new overload to decode a string from it without needing to copy the bytes:

Encoding.GetString(ReadOnlySpan<byte> bytes);

In .NET Standard 2.0 and .NET 4.6 (which I also want to support), I only have the classic overloads:

Encoding.GetString(byte[] bytes);
Encoding.GetString(byte* bytes, int byteCount);

The first one requires a copy of the bytes into an array which I want to avoid.
The second requires a byte pointer, so I thought about getting one from my span, like

Encoding.GetString(Unsafe.GetPointer<byte>(span.Slice(100)))

...but I failed finding an actual method for that. I tried void* Unsafe.AsPointer<T>(ref T value), but I cannot pass a span to that, and didn't find another method dealing with pointers (and spans).

Is this possible at all, and if yes, how?


Solution

  • If you have C# 7.3 or later, you can use the extension made to the fixed statement that can use any appropriate GetPinnableReference method on a type (which Span and ReadOnlySpan have):

    fixed (byte* bp = bytes) {
        ...
    }
    

    As we're dealing with pointers this requires an unsafe context, of course.

    C# 7.0 through 7.2 don't have this, but allow the following:

    fixed (byte* bp = &bytes.GetPinnableReference()) {
        ...
    }