从Span获取Int32<byte>

问题描述 投票:0回答:2

一直在研究跨度、记忆等。我试图了解从 Span 中获取 int 的预期方法

在我读过的所有博客文章中,都暗示正在实施

NonPortableCast<T>
方法,但它似乎已被删除。

我还在 Marc Gravell 的一篇帖子中读到它可能被重命名为

.Cast<T>
,但同样,我在任何地方都找不到它。

因此:

public ReadOnlySpan<byte> MessageBytes {get;set;}
public ReadOnlySpan<byte> ItemLengthBytes => MessageBytes.Slice(0,4);

如何将这 4 个字节转换为 int?

这就是我现在正在做的,这是正确的方法吗?或者有没有更快的方法?

public int ItemLength => Convert.ToInt32(ItemLengthBytes.ToArray());
c#
2个回答
19
投票

在最近的内容中,

Cast
方法现在位于
System.Runtime.InteropServices.MemoryMarshal
下。

但是如果您打算读出单个 int,您可能需要同一类型的

Read
方法。

因此:

public int ItemLength => MemoryMarshal.Read<int>(ItemLengthBytes);

还有

BitConverter.ToInt32
,它与旧的
Convert
api 更相似。

public int ItemLength => BitConverter.ToInt32(ItemLengthBytes);

您编写的内容也可以工作,但它将失去 Span 的很多性能优势,因为每次使用时都会进行额外的内存复制和堆分配

ToArray()


0
投票

之前的答案注释

MemoryMarshal.Read<int>()
...这是正确的,但它是一个较低级别的API,如果您想自动处理Endianness,那么您可以使用
BinaryPrimitives
类来确保Endianness不是问题...

public int ItemLength => BinaryPrimitives.TryReadInt32LittleEndian(ItemLengthBytes, out var resultInt)
    ? resultInt 
    : throw new ArgumentException("Conversion to Int failed");
© www.soinside.com 2019 - 2024. All rights reserved.