Давайте рассмотрим пример, который мне пригодится, когда 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;
}
}
В целом, это позволяет вам использовать методы с «современным» типом возврата в сочетании со «старыми» перегрузками фреймворка - без какого-либо копирования. :)