Float to Byte Array Serialization Over Network
Endianness matters only if your application (or another one you can communicate with) may run on environments with different CPU architectures. If you write, let's say, a Windows application it will currently run only on little-endian CPUs. Moreover you're designing your own communication protocol then endianness is simply part of your specification. If someone else will write, let's say, a compatible application running on PowerPC (!!!) then she will simply adhere to your protocol...

Also note that floating point were sometimes an exception and they did follow different rules than integers. It's pretty uncommon nowadays and, anyway, it's not something you should care about (see previous paragraph).

My suggestion is then to don't care about endianness and save that few CPU cycles you may need to perform any (unneeded) conversion.



Last point more on-topic with Code Review: you should consider to drop that custom implementation that mimic C union, there already is a fast implementation that performs same task: BitConverter.GetBytes(value) (and its counterpart BitConverter.ToSingle(array, 0)).

Doing this way you may also read a bigger buffer (second parameter of ToSingle() is an offset in array) and this will greatly improve performance (over a byte by byte read or multiple array accesses, each one with its bounds checking).

EDIT: note that if performance in this case are a real (measured) issue and you can have an unsafe assembly then you may pick their implementation dropping arguments checking (in release builds):

unsafe static byte[] GetBytes(float value) {
    var bytes = new byte[4];
    fixed (byte* b = bytes)
        *((int*)b) = *(int*)&amp;value;

    return bytes;
}


If access is synchronized then you may even reuse same buffer:

unsafe static void GetBytes(float value, byte[] bytes) {
    Debug.Assert(bytes != null);
    Debug.Assert(bytes.Length == sizeof(float));

    fixed (byte* b = bytes)
    fixed (float* v = &amp;value)
        *((int*)b) = *(int*)v;
}


Note that if you don't really have any performance problem then I'd keep code easier and verifiable and I'd go with BitConverter. ToSingle() implementation is straightforward.

EDIT: a small performance test (just roughly indicative because it's not your true scenario) averaging 100 executions, repeating each trial Int32.MaxValue times to have a significant execution time, keep this in mind when you compare this values (because you see a big difference only because of this):

BitConverter.ToSingle(): 19 milliseconds
Conversion using union style struct: 16 milliseconds
Conversion using unsafe pointer conversion: 7 milliseconds

Code for unsafe conversion is:

static unsafe float ToSingle(byte[] data, int startIndex) {
    fixed (byte* ptr = &amp;data[startIndex]) {
        return *((float*)(int*)ptr);
    }
}


Vice-versa (same test conditions):

BitConverter.GetBytes(): 28 milliseconds
Conversion using union style struct: 15 milliseconds
Conversion using unsafe pointer conversion: 9 milliseconds