2016-08-08 26 views
-1

Ich versuche, eine generische Methode zu schreiben, die jeden Typ von Array in Byte-Array konvertiert.Konvertieren Sie jede Art von Array in Byte [] mit variabler Länge in C#

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. 

Ich verwende dynamische in der Definition, weil ich den Typ online zur Laufzeit kennen lernen.

PS: Ich sah ein anderes Beispiel, das BinaryFormatter und MemoryStream verwendet. Ich möchte das nicht benutzen. (How to convert byte array to any type)

Gibt es eine andere Möglichkeit, dies zu lösen?

+0

Ich würde in den [BinaryWriter] (https://msdn.microsoft.com/en-us/library/system.io.binarywriter (v = vs.110) .aspx? F = 255 & MSPPError = -2147217396 suchen)/[BinaryReader] (https://msdn.microsoft.com/en-us/library/system.io.binaryreader (v = vs.110) .aspx) Klassen. –

+5

Sie können dies beantworten, wenn Sie wissen, ** wie ** Sie jedes beliebige Objekt in ein Byte-Array "konvertieren" können. Die Prämisse, wie sie ist, ist ziemlich unsinnig, da Sie auf binäre Serialisierung zurückgreifen müssen, und genau dafür ist der BinaryFormatter zuständig. Wenn "irgendeine Art von Array" tatsächlich "irgendeinen numerischen Array-Typ" bedeutet, wird es [etwas einfacher] (https://msdn.microsoft.com/en-us/library/system.bitconverter.getbytes (v = vs. 110) .aspx). – CodeCaster

Antwort

1

Es gibt einige Probleme mit dem, was Sie eigentlich fragen, vor allem, wenn Sie keinen Code pro Typ schreiben möchten. Zum Glück gibt es nicht so viele numerische Typen in der BCL, also könnte man alles einmal schreiben oder sogar generieren lassen.

Ein sehr naiver Ansatz ist unten gezeigt:

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

Das gibt die folgende (je nach System endianness):

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

Und so ist die ConvertToByteArray() Methode liefert eine nutzlose Array von 12 Bytes gegeben der Eingabe von int[] { 1, 2, 42 }. Es ist nutzlos, weil Sie nicht wissen, ob das Array 12 Byte, 6 Zeichen, 3 Ints, 3 Floats oder 3 Ganzzahlen ohne Vorzeichen enthält.

Abgesehen davon gibt es eine Menge (Leistungs-) Probleme mit dem angezeigten Code, die ich sicher vereinfachen kann.

Stattdessen finden Sie vielleicht eine andere Lösung für dieses scheinbar XY-Problem.

+0

Welche Version von C# /. Net verwenden Sie? Der einzige Grund, den ich stelle, ist wegen der Beschränkung "struct" auf "ConvertToByteArray" -Methode. Ich dachte, das würde nicht früher kompilieren als C# 6. – IAbstract

+0

@ IAbstract kompiliert mit IdeOne, C# 5 und .NET 4.5 AFAIK. – CodeCaster

+1

Ich werde überprüfen (es ist eine Weile her), um zu sehen, welche Version ich Probleme mit der Einschränkung "struct" hatte. – IAbstract