C# ReadOnlySequence<;字节>;解析

C# ReadOnlySequence<;字节>;解析,c#,C#,因此,我开始尝试使用Span作为消息解析代码。 虽然api看起来很容易理解,但我似乎找不到任何方法将切片转换为值。 例如,我想将ReadOnlySequence转换为int。 当然,我可以调用ToArray并使用BitConverter,但这实际上会创建一个新的数组,这正是我试图避免的 下面是我如何获得切片的示例 var DHCP_OP = buffer.Slice(0, 1); var DHCP_HTYPE = buffer.Slice(1,

因此,我开始尝试使用Span作为消息解析代码。 虽然api看起来很容易理解,但我似乎找不到任何方法将切片转换为值。 例如,我想将ReadOnlySequence转换为int。 当然,我可以调用ToArray并使用BitConverter,但这实际上会创建一个新的数组,这正是我试图避免的

下面是我如何获得切片的示例

        var DHCP_OP = buffer.Slice(0, 1);          
        var DHCP_HTYPE = buffer.Slice(1, 1);
        var DHCP_HLEN = buffer.Slice(2, 1);
        var DHCP_HOPS = buffer.Slice(3, 1);
        var DHCP_XID = buffer.Slice(4, 4);
        var DHCP_SECS = buffer.Slice(8, 2);
        var DHCP_FLAGS = buffer.Slice(10, 2);
        var DHCP_CI_ADDR = buffer.Slice(12, 4);
        var DHCP_YI_ADDR = buffer.Slice(16, 4);
        var DHCP_SI_ADDR = buffer.Slice(20, 4);
        var DHCP_GI_ADDR = buffer.Slice(24, 4);
        var DHCP_CH_ADDR = buffer.Slice(28, 16);
        var DHCP_SNAME = buffer.Slice(44, 64);
        var DHCP_FILE = buffer.Slice(108, 128);
这就是我可能转换为int的方式

      var DHCP_OP = buffer.Slice(0, 1).ToArray();
      var integer = BitConverter.ToInt32(DHCP_OP, 0);
那么这里有什么选择呢?我是不是错过了什么,或者是唯一的选择?
谢谢。

这个问题可能在几个月前就解决了,但以防万一有人在这里寻找同样的问题

您可能正在查找
System.Runtime.InteropServices.MemoryMarshal
。如果使用LayoutType.Sequential或Explicit定义结构,只需调用
MemoryMarshal.Read(mySpan)
即可获得一个已填充的实例。

这是使用.NET Core 3中的
SequenceReader
实现的。 它提供了尝试从
ReadOnlySequence
实例中读取值的方法(当然,只有当有足够的可用数据时才会成功)

SequenceReader
已在此处记录:

  • 对于ref结构本身
  • 用于实际原语值解析
读取简单的
Int32
的用法如下:

//使用System.Buffers;
ReadOnlySequence缓冲区=。。。;
SequenceReader=新的SequenceReader(缓冲区);
if(reader.TryReadLittleEndian(out int integer))
{
//对读取值执行一些操作,读卡器按sizeof(int)前进
}
其他的
{
//可能会中止解析,因为您还无法进一步阅读
}

因为.NET Core 2.1
BitConverter.ToInt32
有一个带有
ReadOnlySpan
参数的重载(戳文档通常有助于解决这样的问题…)嗯,我的libs target.NET标准,因此,唯一的方法是重新定位core?NET标准2.1和更新版本,并使用ReadOnlySpan包含重载(这不是巧合,因为.NET core的“类库”是.NET标准库),顺便说一句,如果您还不知道,Span会隐式转换为ReadOnlySpan。(因此,您无需通过代码将Span的用法更改为ReadOnlySpan。幸运的是,这不是必需的。)因此,似乎我只能在针对.net core时使用这些重载:(现在我从PipeReader获得ReadOnlySequence,似乎重载需要ReadOnlySpan。对于如何在不重新分配内存的情况下进行转换有点困惑。
MemoryMarshal.Read
方法只支持
ReadOnlySpan
,而不支持
ReadOnlySequence
实例。Doh!我不知怎么错过了这一部分,只关注
)>Span
提及。别担心。在我发布答案之前,我甚至不知道除了Span之外还有类似序列的东西