c# - 在基本类型和原始字节之间转换的正确方法?

标签 c#

我需要将简单类型序列化为预定义消息传递协议(protocol)的二进制缓冲区,因此我编写了这个作为示例,它将 2 个字节复制到缓冲区中:

    public static int Copy(this byte[] buffer,Int16 value,int destinationIndex)
    {
        buffer[destinationIndex++] = (byte)(value >> 8);
        buffer[destinationIndex++] = (byte)(value);
        return destinationIndex;
    }

C#感觉很底层,基本就是C代码,敲响了一些警钟。这是在 .NET 中执行此操作的最佳方法,还是有一些更好的框架/语言功能?我也需要一种方法来扭转它,例如:

    public static Int16 Parse(this byte[] buffer, int index)
    {
        var v = buffer[index++] << 8;
        v += buffer[index++];
        return (Int16)v;
    }

最佳答案

很多的方法来进行这些类型的翻译;从历史上看,BitConverter 在这里很有用,但它相当容易分配,尤其是在序列化时 - 它每次返回一个新的 byte[]。不幸的是,它还具有依赖于 CPU 的特性,这意味着:它以当前 CPU 使用的任何方式返回数据 - 不适合序列化,因为写入和读取机器可能是不同的体系结构。

最近,BinaryPrimitives 是一个更有吸引力的选择,因为它不分配。它在 spans 上工作,这意味着它可以在字节数组上工作,但它也可以在非托管内存、堆栈分配的 block 、固定大小的缓冲区和其他场景上工作。它在字节顺序方面也有明确的定义,使用 JIT 的新功能将 CPU 字节顺序解释为不变式并删除不必要的代码,以便在运行时只保留“正确”的代码。

在这种情况下,您显示的是大端编码,因此适当的方法是 BinaryPrimitives.[Try]ReadInt16BigEndian(...)BinaryPrimitives.[Try] WriteInt16BigEndian(...)

关于c# - 在基本类型和原始字节之间转换的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59774345/

相关文章:

c# - 如何有效地写入长度前缀二进制数据

c# - 在 View 中的字符串中使用 Razor

c# - 如何在运行时在 IEnumerable<T> 上创建动态多属性 Select?

C# 项目和命名空间问题

c# - 如何显示带有客户端验证的验证摘要?

C# 返回一个列表或一个 int

c# - 不同域上的不同网站,一个 .NET MVC 应用程序?

c# - 使用 LINQ to SQL 的条件投影

c# - 如何解决 Exception :Call was rejected by callee. (Exception from HRESULT : 0x80010001 (RPC_E_CALL_REJECTED)) in C#?

c# - 将 C# COM 对象数组传递给 VB6