C# 如何将基元[]转换为字节[]

C# 如何将基元[]转换为字节[],c#,binary-serialization,C#,Binary Serialization,对于基元数组的序列化,我想知道如何将基元[]转换为相应的字节[]。(即int[128]到字节[512],或ushort[]到字节[…) 目标可以是内存流、网络消息、文件或任何内容。 目标是提高性能(序列化和反序列化时间),以便能够使用某些流一次性写入字节[],而不是通过所有值循环,或者使用某些转换器进行分配 已经探讨了一些解决方案: 写入/读取的常规循环 //array = any int[]; myStreamWriter.WriteInt32(array.Length); for(int i

对于基元数组的序列化,我想知道如何将基元[]转换为相应的字节[]。(即int[128]到字节[512],或ushort[]到字节[…) 目标可以是内存流、网络消息、文件或任何内容。 目标是提高性能(序列化和反序列化时间),以便能够使用某些流一次性写入字节[],而不是通过所有值循环,或者使用某些转换器进行分配

已经探讨了一些解决方案:

写入/读取的常规循环

//array = any int[];
myStreamWriter.WriteInt32(array.Length);
for(int i = 0; i < array.Length; ++i)
   myStreamWriter.WriteInt32(array[i]);
而C#的电话:

byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
   arrayI[i] = i;

// delegate call
fptr(arrayI, out arrayB);
byte[]arrayB=null;
int[]arrayI=新int[128];
对于(int i=0;i<128;++i)
arrayI[i]=i;
//代表呼叫
fptr(arrayI,out arrayB);
我成功地将int(128)检索到C++中,切换数组长度,并将右边的地址与我的“输出”var关联,但是c++只检索字节[1 ]作为返回。似乎我无法如此轻松地破解托管变量

所以我真的开始认为我想要实现的所有这些类型转换在C#(int[]->byte[],bool[]->byte[],double[]->byte[])中都不可能不分配/复制

我缺少什么?

如何使用


请注意,
BlockCopy
仍在幕后分配/复制。我相当肯定,这在托管代码中是不可避免的,而
BlockCopy
可能与它在这方面的表现一样好。

你能更具体地说明你想做什么吗?您正在序列化数组?连载在哪里?硬盘可能是你真正的瓶颈。也许您应该使用
byte[]
来保存原始数据(那时不需要序列化,但检索数据很棘手)。我很惊讶常规循环的性能如此糟糕。我觉得它应该更好,仅仅循环两到三百个值听起来并不像什么会导致性能问题。也许你应该进一步研究这一点,而不是将其视为不可避免的性能影响。我自己没有做过,但如果你想看的话,这可能是一个起点。我是在快速处理图像中的位图数据的环境中遇到这个问题的,但考虑到这也只是处理数组,如果您真的需要性能,它可能对您有用。@Sinatr我编辑了我的顶部消息,但目标只是对基元值的数组进行二进制序列化(可以是byte、sbyte、short、ushort、int、sint、long、slong、double、decimal、DateTime、TimeSpan或bool)尽可能快。目标不重要,它可以是内存流、网络消息或文件。@Chris我忘了说,但我已经尝试了固定块,但没有成功,我甚至尝试了直接IL代码强制转换,但我总是有一个InvalidCastException,因为结果是des
BlockCopy
用于基本值类型数组?(我想是的)这可能是一个很好的方法。我今天将尝试这种方法,使用某种静态锁定的byte[]缓冲区,以避免多次分配并保持线程安全。感谢您的想法,我使用这种方法,除了十进制类型。
byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
   arrayI[i] = i;

// delegate call
fptr(arrayI, out arrayB);
// serialize
var intArray = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var byteArray = new byte[intArray.Length * 4];
Buffer.BlockCopy(intArray, 0, byteArray, 0, byteArray.Length);

// deserialize and test
var intArray2 = new int[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, intArray2, 0, byteArray.Length);
Console.WriteLine(intArray.SequenceEqual(intArray2));    // true