span <T>和流

Chr*_*ods 9 c# .net-core

我已经读了一段时间了,只是尝试实现它。但是,尽管我可以跨度工作,但是我无法弄清楚如何像示例中那样使流接受它。其他示例也显示了int.parse支持范围,但我找不到使之成为可能的重载或扩展。

我在.net Standard 2.0和.net core 2.0中都尝试过。

请指出正确的方向以使其正常工作。

编辑:代码示例将是:

    Span<Byte> buffer = new Span<byte>();
    int bytesRead = stream.Read(buffer);
Run Code Online (Sandbox Code Playgroud)

Pan*_*vos 11

.NET Core 2.1支持流的跨度结果。如果您检查Stream的当前源代码,您会看到它具有诸如Read(Span)的重载,可以读入a Span<byte>而不是byte[],或者Write(ReadOnlySpan)可以写成a ReadOnlySpan<byte>而不是a byte[],该重载使用Memory等。

若要定位.NET Core 2.1,您必须至少安装Visual Studio 2017 15.7 Preview 4最新的.NET Core 2.1 SDK


Tim*_*imo 5

让我们看一个我方便使用的示例,它Span<T>恰好来自PipeWriter

var bufferSpan = pipeWriter.GetSpan(count);
stream.Write( /* Darn, I need an array, because no Span<T> overloads outside Core 2.1! */ );
Run Code Online (Sandbox Code Playgroud)

尝试获取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!
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

总而言之,这使您可以将具有“现代”返回类型的方法与“旧”框架重载结合使用-无需任何复制。:)