在c#中将任何类型的数组转换为可变长度的byte []

时间:2016-08-08 15:07:12

标签: c# arrays bytearray

我正在尝试编写一个将任何类型的数组转换为字节数组的泛型方法。

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.

我在定义中使用dynamic,因为我在运行时了解了在线类型。

PS:我看到另一个使用BinaryFormatter和MemoryStream的例子。我不想用它。 (How to convert byte array to any type

还有其他可能的解决方法吗?

1 个答案:

答案 0 :(得分:1)

您实际要问的内容存在一些问题,特别是如果您不想为每种类型编写代码。幸运的是,BCL中没有那么多数字类型,所以你可以把它全部写出来甚至让它生成。

一种非常天真的方法如下所示:

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");
    }
}

这将输出以下内容(取决于您的系统的字节顺序):

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

所以ConvertToByteArray()方法在给定int[] { 1, 2, 42 }的输入的情况下提供了一个无用的12字节数组。它没用,因为你不知道该数组是否包含12个字节,6个字符,3个整数,3个浮点数或3个无符号整数。

除此之外,显示的代码存在很多(性能)问题,我确信可以简化。

相反,也许你可以找到另一个解决这个看似XY问题的方法。