在 C# 中转换数组而不进行复制

问题描述 投票:0回答:3

我有一系列短裤:

short[] data;

我有一个将字节写入文件的函数:

void Write(byte[] data);

我无法控制此功能,也无法更改它。有没有一种方法可以编写我的短裤数组,而无需先制作冗余副本以将其转换为字节?

类似这样的事情:

Write((byte[])data);

我不关心字节序。我希望将 Shorts 的内存表示形式写入文件,无论 Shorts 的机器表示形式是什么。我知道这种类型转换不能用于任何包含引用的非 POD 类型,但短裤应该可以完美转换。转换应该产生一个字节数组,其大小是指向相同内存的两倍。

如果这在 C# 中是不可能的,那么 CLR 中是否有任何东西使得这不可能,或者只是 C# 的限制?

c# arrays casting
3个回答
5
投票

我不关心字节序。我希望将 Shorts 的内存表示写入文件中,无论 Shorts 的机器表示是什么。

这是第一个不可能的事情 - 字节序改变了内存表示,因此从数组中第一个 Short 的地址开始读取连续字节地址将导致不同的字节模式,具体取决于机器字节序。

第二个不可能的事情是 CLR 中的数组具有与数据一起编码的类型和长度信息。您不能更改此标头信息,否则会破坏垃圾收集器。因此,给定一个

short[]
数组,您无法将其转换为
byte[]
数组。您可能会使用 C++ clr 或不安全代码获得
byte
指针,但您仍然无法获得 CLR 数组。

如果您确实无法控制采用字节数组的代码,您也许可以更改操作短裤的代码。在字节数组上使用

MemoryStream
将允许您读取和写入数据,您可以将数组包装为
IList<short>
,或者您可以只创建访问器扩展函数以将数据作为 Shorts 获取。

public sealed class ShortList :IList<short>
{
    private readonly byte[] _array;

    public short this[int index]
    {
        get { return (short)_array[index/2]<<8 | _array[index/2+1] ; }
    }

    public int Count
    {
        get { return _array.Length/2; }
    }

    ... many more methods in IList

0
投票

有一种非常低级的方法,您必须更改内存中告诉 CLR 这是一个 Short[] 的字节,并将它们替换为一些告诉 CLR 这是一个 byte[] 的字节。在您必须调整数组大小并创建正确类型的指针以获得编译器支持之后。

看看这里http://blogs.ugidotnet.org/leonardo/archive/2023/11/24/water-in-wine-csharp-array-cast.aspx


-3
投票

怎么样

Write(data.SelectMany(x => BitConverter.GetBytes(x)).ToArray());
© www.soinside.com 2019 - 2024. All rights reserved.