code_fodder code_fodder - 1 month ago 14
C# Question

c# use a generic function to pass parameter to a function with many overloads

I am trying to create the following function:

public static byte[] ValueToBigEndian<T>(T data)
{
byte[] bytes;
// We want to use big endian
if (BitConverter.IsLittleEndian)
{
bytes = BitConverter.GetBytes(data).Reverse().ToArray();
//bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data)); // probabl don't need this
}
else
{
// Host is big endian already
bytes = BitConverter.GetBytes(data;
//bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data)); // probabl don't need this
}

return bytes;
}


So here I am using
BitConverter.GetBytes(...)
which is not generic, but it has many overloads (
ushort
,
int
,
bool
,
ulong
,
long
,
short
, etc...).

I am trying to avoid writing matching overloaded functions for each of these, so my idea was to use a generic function. IMHO this would run fine until someone tries to use a type that is not in the overload list, and then the compiler would complain. But the compiler immediately complains since there is no overload for type
T
.

The error I get is


Error CS1503 Argument 1: cannot convert from 'T' to 'bool'


Is there a way to achieve what I am attempting here?

Answer

Logic would state that this could be done. However, there is no common type (other than Object) that all value types inherit from that any overload of BitConverter.GetBytes would accept as a parameter.

One thing you could do instead is to instead use a generic parameter and just trust that the value passed into the method is one of the valid parameter types for BitConverter.GetBytes:

public static byte[] ValueToBigEndian(dynamic data)
{
    byte[] bytes = BitConverter.GetBytes(data);

    if (BitConverter.IsLittleEndian)
        Array.Reverse(bytes);

    return bytes;
}

I'd prefer this method over using Reflection, as it's easier to understand what is going on and I believe it would also run faster (untested claim). However, like Reflection, you would have to do your own type checking to catch occasions when an object of an incompatible type is passed. (This can be handled by a try-catch, but I'm not sure if that would necessarily be considered "best practice".)