跨度<T> 和流

span<T> and streams

我已经阅读了一段时间有关 span 的内容,并且刚刚尝试实现它。然而,虽然我可以让 span 工作,但我无法弄清楚如何让流像示例中那样接受它。其他示例也显示 int.parse 支持跨度,但我找不到使其成为可能的重载或扩展。

.net standard 2.0.net core 2.0我都试过了

请为我指明正确的方向以完成这项工作。

代码示例

Span<Byte> buffer = new Span<byte>();
int bytesRead = stream.Read(buffer);

.NET Core 2.1 支持来自流的 Span 结果。如果您检查 Stream you'll see it has overloads like Read(Span) that read into a Span<byte> instead of byte[], or Write(ReadOnlySpan) 的当前源代码,它可以写出 ReadOnlySpan<byte> 而不是 byte[],使用内存等的重载

要以 .NET Core 2.1 为目标,您至少需要安装 Visual Studio 2017 15.7 Preview 4 or the latest SDK for .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;
    }
}

总而言之,这使您可以将具有 'modern' return 类型的方法与 'old' 框架重载结合使用 - 无需任何复制。 :)