span <t>和流

时间:2018-04-28 16:22:22

标签: c# .net-core

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

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

请指出我正确的方向来完成这项工作。

编辑:代码示例如下:

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

2 个答案:

答案 0 :(得分:6)

.NET Core 2.1支持来自流的跨度结果。如果您检查例如Stream的当前源代码,您会看到它有Read(Span)之类的重载,这些重载会读入Span<byte>而不是byte[],或{{3可以写出ReadOnlySpan<byte>而不是byte[],使用内存等的重载。

要定位.NET Core 2.1,您必须至少安装Write(ReadOnlySpan)Visual Studio 2017 15.7 Preview 4

答案 1 :(得分:2)

我们来看一个方便的示例,其中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;
    }
}

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