span<T> и потоки
Я уже давно читаю о span и просто пытаюсь его реализовать. Однако, хотя я могу заставить span работать, я не могу понять, как заставить поток принять его, как они делают в примерах. Другие примеры показывают также поддержку int.parse, но я не могу найти перегрузки или расширения, которые делают это возможным.
Я пробовал это как в.net Standard 2.0, так и в.net core 2.0.
Пожалуйста, укажите мне правильное направление, чтобы сделать эту работу.
Изменить: Пример кода будет:
Span<Byte> buffer = new Span<byte>();
int bytesRead = stream.Read(buffer);
2 ответа
Span-результаты из потоков поддерживаются в.NET Core 2.1. Если вы проверите текущий исходный код, например, Stream, вы увидите, что у него есть перегрузки, такие как Read (Span), которые читают в Span<byte>
вместо byte[]
или Write(ReadOnlySpan), который может записать ReadOnlySpan<byte>
вместо byte[]
, перегрузки, которые используют память и т. д.
Чтобы ориентироваться на.NET Core 2.1, вам нужно установить как минимум Visual Studio 2017 15.7 Preview 4 или последний SDK для.NET Core 2.1.
Давайте посмотрим на пример, который мне пригодится, где Span<T>
случается из PipeWriter
,
var bufferSpan = pipeWriter.GetSpan(count);
stream.Write( /* Darn, I need an array, because no Span<T> overloads outside Core 2.1! */ );
Попробуй получить Memory<T>
вместо Span<T>
, для которого вы можете получить базовый массив (за исключением некоторых экзотических обстоятельств).
var bufferMemory = pipeWriter.GetMemory(count); // Instead of GetSpan()
var bufferArraySegment = bufferMemory.GetUnderlyingArray();
stream.Write(bufferArraySegment.Array, bufferArraySegment.Offset, bufferArraySegment.Count); // Yay!
GetUnderlyingArray()
Вот небольшой метод расширения:
/// <summary>
/// Memory extensions for framework versions that do not support the new Memory overloads on various framework methods.
/// </summary>
internal static class MemoryExtensions
{
public static ArraySegment<byte> GetUnderlyingArray(this Memory<byte> bytes) => GetUnderlyingArray((ReadOnlyMemory<byte>)bytes);
public static ArraySegment<byte> GetUnderlyingArray(this ReadOnlyMemory<byte> bytes)
{
if (!MemoryMarshal.TryGetArray(bytes, out var arraySegment)) throw new NotSupportedException("This Memory does not support exposing the underlying array.");
return arraySegment;
}
}
В общем, это позволяет вам использовать методы с "современным" типом возврата в сочетании со "старыми" перегрузками фреймворка - без какого-либо копирования.:)