12

在 C# .Net(3.5 及更高版本)中是否可以将变量复制到 byte[] 缓冲区中而不会在进程中创建任何垃圾?

例如:

int variableToCopy = 9861;

byte[] buffer = new byte[1024];
byte[] bytes = BitConverter.GetBytes(variableToCopy);
Buffer.BlockCopy(bytes, 0, buffer, 0, 4);

float anotherVariableToCopy = 6743897.6377f;
bytes = BitConverter.GetBytes(anotherVariableToCopy);
Buffer.BlockCopy(bytes, 0, buffer, 4, sizeof(float));

...

创建变成垃圾的 byte[] bytes 中间对象(假设不再持有 ref)...

我想知道是否可以使用按位运算符将变量直接复制到缓冲区中而无需创建中间字节 []?

4

2 回答 2

7

使用指针是最好也是最快的方法:你可以用任意数量的变量来做到这一点,不会浪费内存,固定语句有一点开销但它太小了

        int v1 = 123;
        float v2 = 253F;
        byte[] buffer = new byte[1024];
        fixed (byte* pbuffer = buffer)
        {
            //v1 is stored on the first 4 bytes of the buffer:
            byte* scan = pbuffer;
            *(int*)(scan) = v1;
            scan += 4; //4 bytes per int

            //v2 is stored on the second 4 bytes of the buffer:
            *(float*)(scan) = v2;
            scan += 4; //4 bytes per float
        }
于 2013-03-09T05:33:34.167 回答
3

为什么你不能这样做:

byte[] buffer = BitConverter.GetBytes(variableToCopy);

请注意,这里的数组不是对原始 Int32 存储的间接访问,它在很大程度上是一个副本。

您可能担心bytes在您的示例中相当于:

unsafe
{
    byte* bytes = (byte*) &variableToCopy;
}

..但我向你保证,事实并非如此;它是源 Int32 中字节的逐字节副本。

编辑

根据您的编辑,我认为您想要这样的东西(需要不安全的上下文):

public unsafe static void CopyBytes(int value, byte[] destination, int offset)
{
    if (destination == null)
        throw new ArgumentNullException("destination");

    if (offset < 0 || (offset + sizeof(int) > destination.Length))
        throw new ArgumentOutOfRangeException("offset");

    fixed (byte* ptrToStart = destination)
    {
        *(int*)(ptrToStart + offset) = value;
    }
}
于 2013-03-09T05:18:25.007 回答