-1

I am trying to write a generic method which converts any type of array to byte array.

method definition:

    public byte[] convert_item_to_bytes(dynamic items)
    {
        byte[] bytearr = ??
            //I tried blockcopy, but i am not getting the correct number of elements
            //Buffer.BlockCopy(items, 0, bytearr, 0, items.Length );

        return bytearr;
    }


examples of my method calls:

         convert_item_to_bytes(new int16[]{0x1234, 0x4567, 0x9574});
         convert_item_to_bytes(new int32[]{0x3545, 0x3352, 0x9642, 0x5421});
         convert_item_to_bytes(new uint64[]{0x4254, 0x8468});
         //etc.... my method calls can also be of float type.

I am using dynamic in the definition because i get to know the type online at runtime.

PS: I saw an another example which uses BinaryFormatter and MemoryStream. I do not want to use that. (How to convert byte array to any type)

Is there any other possible way to solve this?

Community
  • 1
  • 1
Pratul Jn
  • 69
  • 8
  • I'd look into the [BinaryWriter](https://msdn.microsoft.com/en-us/library/system.io.binarywriter(v=vs.110).aspx?f=255&MSPPError=-2147217396)/[BinaryReader](https://msdn.microsoft.com/en-us/library/system.io.binaryreader(v=vs.110).aspx) classes. – Glorin Oakenfoot Aug 08 '16 at 15:09
  • 5
    You can answer this if you know **how** you can "convert" any arbitrary object to a byte array. The premise as-is is quite nonsensical, as you _will_ have to resort to binary serialization, which is exactly what the BinaryFormatter is for. If "any type of array" actually means "any numeric type of array" it [becomes a bit easier](https://msdn.microsoft.com/en-us/library/system.bitconverter.getbytes(v=vs.110).aspx). – CodeCaster Aug 08 '16 at 15:09

1 Answers1

1

There's quite some issues with what you're actually asking, especially if you don't want to write code per type. Luckily there aren't that many numeric type in the BCL, so you could write it all out once or even let it be generated.

A very naive approach is shown below:

public static void Main()
{
    int[] intArray = new int[] { 1, 2, 42, };

    byte[] intOutput = ConvertToByteArray(intArray, sizeof(int));

    for (int i = 0; i < intOutput.Length; i++)
    {
        Console.Write("{0:x2} ", intOutput[i]);
        if ((i + 1) % singleItemSize == 0)
        {
            Console.WriteLine();
        }
    }
}

private static byte[] ConvertToByteArray<T>(T[] input, int singleItemSize)
    where T : struct, 
        IComparable, 
        IComparable<T>, 
        IConvertible, 
        IEquatable<T>, 
        IFormattable
{
    var outputArray = new byte[input.Length * singleItemSize];

    // Iterate over the input array, get the bytes for each value and append them to the output array.
    for (int i = 0; i < input.Length; i++)
    {
        var thisItemBytes = GetBytes(input[i]);
        Buffer.BlockCopy(thisItemBytes, 0, outputArray, i * singleItemSize, singleItemSize);
    }

    return outputArray;
}

private static byte[] GetBytes<T>(T input)
    where T : struct, 
        IComparable, 
        IComparable<T>, 
        IConvertible, 
        IEquatable<T>, 
        IFormattable
{
    if (typeof(T) == typeof(int))
    {
        return BitConverter.GetBytes(Convert.ToInt32(input));
    }
    else if (typeof(T) == typeof(float))
    {
        return BitConverter.GetBytes(Convert.ToSingle(input));
    }
    else
    {
        throw new ArgumentException("T");
    }
}

This outputs the following (depending on your system's endianness):

01 00 00 00 
02 00 00 00 
2a 00 00 00 

And so the ConvertToByteArray() method delivers a useless array of 12 bytes given the input of int[] { 1, 2, 42 }. It is useless because you don't know whether that array contains 12 bytes, 6 chars, 3 ints, 3 floats or 3 unsigned integers.

Apart from that, there's a lot of (performance) problems with the shown code, which I'm sure can be simplified.

Instead perhaps you can find another solution for this seemingly XY problem.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Which version of C#/.Net are you using? Only reason I ask is because of the `struct` constraint on `ConvertToByteArray` method. I thought that would not compile in earlier than C# 6. – IAbstract Aug 08 '16 at 18:10
  • @IAbstract compiled using IdeOne, C# 5 and .NET 4.5 AFAIK. – CodeCaster Aug 08 '16 at 18:13
  • 1
    I'll check (it's been a while) to see what version I may have had problems with the `struct` constraint. – IAbstract Aug 08 '16 at 18:15
  • @IAbstract alright. As far as I know it has always worked, but feel free to enlighten me! – CodeCaster Aug 08 '16 at 18:17
  • @CodeCaster I will try your code. I am using .NET 4.5 The reason I want to convert to byte array is to transfer it to another tool. So is it simpler and faster to use BinaryFormatter and MemoryStream? – Pratul Jn Aug 09 '16 at 10:09
  • I have many paramters to convert. So, I want to put everything into a byte array and then transfer it. – Pratul Jn Aug 09 '16 at 10:12