一直在研究跨度、记忆等。我试图了解从 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());
在最近的内容中,
Cast
方法现在位于System.Runtime.InteropServices.MemoryMarshal
下。
Read
方法。
因此:
public int ItemLength => MemoryMarshal.Read<int>(ItemLengthBytes);
BitConverter.ToInt32
,它与旧的 Convert
api 更相似。
public int ItemLength => BitConverter.ToInt32(ItemLengthBytes);
您编写的内容也可以工作,但它将失去 Span 的很多性能优势,因为每次使用时都会进行额外的内存复制和堆分配
ToArray()
。
之前的答案注释
MemoryMarshal.Read<int>()
...这是正确的,但它是一个较低级别的API,如果您想自动处理Endianness,那么您可以使用BinaryPrimitives
类来确保Endianness不是问题...
public int ItemLength => BinaryPrimitives.TryReadInt32LittleEndian(ItemLengthBytes, out var resultInt)
? resultInt
: throw new ArgumentException("Conversion to Int failed");