C# - 我可以使用数组初始化器从另一个字节数组中构建一个字节数组吗?

Posted

技术标签:

【中文标题】C# - 我可以使用数组初始化器从另一个字节数组中构建一个字节数组吗?【英文标题】:C# - Can I use an array initializer to build one byte array out of another? 【发布时间】:2016-12-31 19:55:17 【问题描述】:

我想使用数组初始值设定项从另一个字节数组以及形成标题/结尾的其他一些字节构建一个字节数组。基本上,我想做这样的事情:

byte[] DecorateByteArray(byte[] payload)

    return new byte[]  0, 1, 2, payload.GetBytes(), 3, 4, 5;

上面的GetBytes()是虚构的,很遗憾。

有什么好的/优雅的方法可以做到这一点?我通过使用BinaryWriter 将所有内容写入MemoryStream 解决了这个问题,然后使用MemoryStream.ToArray() 将其转换为字节数组,但感觉有点笨拙。

【问题讨论】:

这很烦人,因为我不想关闭这个as a dupe...但是你的具体措辞让它对此免疫....所以回答你烦人的措辞:不 【参考方案1】:

你能得到的最接近的是:

byte[] DecorateByteArray(byte[] payload) =>
    new byte[]  0, 1, 2  
       .Concat(payload)
       .Concat(new byte[]  3, 4, 5 )
       .ToArray();

但那将是相当低效的。你最好做这样的事情:

static T[] ConcatArrays<T>(params T[][] arrays)

    int length = arrays.Sum(a => a.Length);
    T[] ret = new T[length];
    int offset = 0;
    foreach (T[] array in arrays)
    
        Array.Copy(array, 0, ret, offset, array.Length);
        offset += array.Length;
    
    return ret;

(考虑在适当的情况下也使用Buffer.BlockCopy。)

然后调用它:

var array = ConcatArrays(new byte[]  0, 1, 2 , payload, new byte[]  3, 4, 5 );

【讨论】:

【参考方案2】:

您可以创建一个新集合,它是 List&lt;byte&gt;,但它的重载为 Add,会添加整个字节数组:

public class ByteCollection: List<byte>

    public void Add(IEnumerable<byte> bytes)
    
        AddRange(bytes);
    

然后,您可以使用此类型的集合初始值设定项来提供单个字节或字节序列,然后如果需要数组,您可以将其转回数组:

byte[] DecorateByteArray(byte[] payload)

    return new ByteCollection()  0, 1, 2, payload, 3, 4, 5 .ToArray();

【讨论】:

我不知道你可以覆盖 add 所以你可以初始化一个该死的集合! @johnny5 我没有覆盖它。我超载了它。很大的区别。添加是sealed,因此不能被覆盖。 我的意思是超载,今天早上没喝咖啡【参考方案3】:

一种简单的方法是将每个部分分解,然后将它们连接起来

byte[] DecorateByteArray(byte[] payload)
  
    return new byte[]  0, 1, 2
        .Concat(payload.GetBytes())
        .Concat(new byte[]  3, 4, 5);

【讨论】:

以上是关于C# - 我可以使用数组初始化器从另一个字节数组中构建一个字节数组吗?的主要内容,如果未能解决你的问题,请参考以下文章

C#在循环内多次重新初始化数组

从另一个数组的指针和大小初始化数组

使用 C# 从字节数组中解码 dtmf

C#中字节数组的递增指针

C# 位图图像、字节数组和流!

使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#