You can play a trick with a help of IntPtr and Marshal in order to convert any struct (including byte, ushort and ulong):
// Disclaimer: the structure will be reversed as a whole, not field by field
public static byte[] ToLEByteArray<T>(T value) where T: struct {
int size = Marshal.SizeOf(typeof(T));
byte[] bytes = new byte[size];
IntPtr p = Marshal.AllocHGlobal(size);
try {
Marshal.StructureToPtr(value, p, true);
Marshal.Copy(p, bytes, 0, size);
}
finally {
Marshal.FreeHGlobal(p);
}
// If it was big endian, reverse it
if (!BitConverter.IsLittleEndian)
Array.Reverse(bytes);
return bytes;
}
....
Byte b = 123;
ushort s = 123;
ulong l = 123;
Byte[] result_byte = ToLEByteArray(b);
Byte[] result_ushort = ToLEByteArray(s);
Byte[] result_ulong = ToLEByteArray(l);
....
int i = 123456;
Byte[] result_int = ToLEByteArray(i);
EDIT: what's wrong with the implementation in the question? (from the comment).
Or, restating the question, what is that stuff with IntPtr, Marshal for?
The main issue of the question's implementation is the initial conversion to ulong:
// all the arguments will be converted to ulong
public static byte[] UnsignedIntegerToLEByteArray(ulong value)
In order to illustrate the problem, imagine, that we have two values
Byte x = 0x12; // 18
ulong u = 0x0000000000000012; // 18
and the expected output is
new byte[] {0x12}; // for a single byte
new byte[] {0x12, 0, 0, 0, 0, 0, 0, 0}; // for 8 bytes, i.e. ulong
however, the actual output will be
new byte[] {0x12, 0, 0, 0, 0, 0, 0, 0};
for both byte and ulong. This misbehaviour can lead to problems if you, say, want to write down numeric values (byte, short, ulong etc.), to a binary file, pass them to a binary stream etc:
using (Stream stm = ...) {
...
Byte[] buffer = UnsignedIntegerToLEByteArray(...);
stm.Write(buffer, offset, buffer.Length); // <- the (possibly!) erroneous write
...
}