跨度<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' 框架重载结合使用 - 无需任何复制。 :)
我已经阅读了一段时间有关 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' 框架重载结合使用 - 无需任何复制。 :)