I am having to deal with raw bytes in a project and I need to basically do something like this
byte[] ToBytes(){
byte[] buffer=new byte[somelength];
byte[] tmp;
tmp=BitConverter.GetBytes(SomeShort);
buffer[0]=tmp[0];
buffer[1]=tmp[1];
tmp=BitConverter.GetBytes(SomeOtherShort);
buffer[2]=tmp[0];
buffer[3]=tmp[1];
}
I feel like this is so wrong yet I can't find any better way of doing it. Is there an easier way?
BinaryWriter is very efficient:
byte[] ToBytes() {
var ms = new MemoryStream(somelength);
var bw = new BinaryWriter(ms);
bw.Write(SomeShort);
bw.Write(SomeOtherShort);
return ms.ToArray();
}
You don't need to initialize tmp
to a new array. BitConverter.GetBytes
creates a new array and returns it for you. There's not much you can do about GetBytes
but you can use methods like Buffer.BlockCopy
to simplify the copy operation.
If you're not doing this in a performance-critical piece of code, you can go a bit LINQy and do things like:
IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();
If you know the size beforehand (have a set of value types) you could use a struct and assign your values in the struct. Then use unsafe
code to copy the raw bytes. I would still advise against it unless it's really necessary for speed purposes. And you might think it's painful :)
private struct MyStruct
{
public short A;
public short B;
public MyStruct(short a, short b)
{
A = a;
B = b;
}
}
private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
byte[] buffer = new byte[4]; // where 4 is the size of the struct
fixed (byte* ptr = buffer)
{
*((MyStruct*)ptr) = myStruct;
}
return buffer;
}
Just bit-shift...
buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);
This also means you are in complete control of the endian-ness (in this case, little-endian)
You can make your code a little shorter by using Array.Copy, but no there isn't any GetBytes overload or equivalent in BitConverter that puts the bytes directly into your buffer.
Maybe BinaryWriter on a MemoryStream is what you want?
Note that by adopting the API conventions of BitConverter which you don't like, you're causing the same problem for users of your class. Instead, write a method which accepts a BinaryWriter and serializes your class into it, this extends nicely when your class is embedded in some other object.