Могу ли я получить указатель на 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);