I'd like to use an array initializer to build one byte array out of another byte array as well as some other bytes that form a header/trailer. Basically, I'd like to do something like this:
byte[] DecorateByteArray(byte[] payload)
{
return new byte[] { 0, 1, 2, payload.GetBytes(), 3, 4, 5};
}
GetBytes()
above is fictional, unfortunately.
Is there any nice/elegant way to do this? I solved this by using a BinaryWriter
to write everything to a MemoryStream
, and then converting this into a byte array with MemoryStream.ToArray()
, but it feels kind of clunky.
The closest you could get would be:
byte[] DecorateByteArray(byte[] payload) =>
new byte[] { 0, 1, 2 }
.Concat(payload)
.Concat(new byte[] { 3, 4, 5 })
.ToArray();
That would be pretty inefficient though. You'd be better off doing something like:
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;
}
(Consider using Buffer.BlockCopy
too, where appropriate.)
Then call it with:
var array = ConcatArrays(new byte[] { 0, 1, 2 }, payload, new byte[] { 3, 4, 5 });
You can create a new collection that is a List<byte>
, but that has an overload of Add
that adds a whole array of bytes:
public class ByteCollection: List<byte>
{
public void Add(IEnumerable<byte> bytes)
{
AddRange(bytes);
}
}
This then lets you use the collection initializer for this type to supply either a single byte or a sequence of bytes, which you can then turn back into an array if you need an array:
byte[] DecorateByteArray(byte[] payload)
{
return new ByteCollection() { 0, 1, 2, payload, 3, 4, 5 }.ToArray();
}
One easy way is to break out each into parts and then concat them
byte[] DecorateByteArray(byte[] payload)
{
return new byte[] { 0, 1, 2}
.Concat(payload.GetBytes())
.Concat(new byte[] { 3, 4, 5});
}