Могу ли я получить указатель на Span?

У меня есть (ReadOnly)Span<byte> из которого я хочу декодировать строку.

Только в.NET Core 2.1 у меня есть новая перегрузка для декодирования строки из нее без необходимости копировать байты:

Encoding.GetString(ReadOnlySpan<byte> bytes);

В.NET Standard 2.0 и.NET 4.6 (которые я также хочу поддерживать) у меня есть только классические перегрузки:

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

Первый требует копирования байтов в массив, который я хочу избежать.
Второй требует указатель байта, поэтому я подумал о том, чтобы получить один из моего диапазона, как

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

... но мне не удалось найти настоящий метод для этого. Я старался void* Unsafe.AsPointer<T>(ref T value), но я не могу передать диапазон, и не нашел другого метода, имеющего дело с указателями (и диапазонами).

Возможно ли это вообще, и если да, то как?

2 ответа

Решение

Если у вас C# 7.3 или новее, вы можете использовать расширение, сделанное для fixed утверждение, которое может использовать любой подходящий GetPinnableReference метод по типу (который Span а также ReadOnlySpan иметь):

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

Поскольку мы имеем дело с указателями, это требует unsafe контекст, конечно.

В C# 7.0 до 7.2 этого нет, но разрешите следующее:

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

Попробуй это:

Span<byte> bytes = ...;
string s = Encoding.UTF8.GetString((byte*)Unsafe.AsPointer(ref bytes.GetPinnableReference()),
    bytes.Length);
Другие вопросы по тегам