Exception: "Kann System.Byte[*] nicht in System.Byte[] konvertieren"

  • VB.NET
  • .NET (FX) 4.0

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    Wie gesagt: Byte[*] ist ein Array mit unterer Grenze. Jedes Array ist aber vom Typ System.Array, daher kannst du es auch einfach casten...

    VB.NET-Quellcode

    1. 'Jetzt steht ein Byte[*] in obj
    2. Dim obj As Object = Array.CreateInstance(GetType(Byte), New Integer() {1}, New Integer() {2})
    3. '==> Konvertiere es zu Array
    4. Dim arr As Array = DirectCast(obj, Array)
    5. 'Kopiere die Array-Daten in arr
    6. Dim bytes(p.Length - 1) As Byte
    7. Buffer.BlockCopy(p, 0, byteInst, 0, p.Length)


    Nicht jedes eindimensionale Array muss zwangsweise den ersten Index 0 haben. Um nun 0-basierte Arrays und nicht 0-basierte Arrays zu unterscheiden, wird eben das * eingeführt. Fakt ist, dass nicht 0-basierte Arrays nicht durch die normale Indexierung zugänglich gemacht werden können, sonst dürfte man ja auch nicht For i As Integer = 0 To array.Length - 1 schreiben, sondern müsste jedes mal For i As Integer = array.GetLowerBounds(0) To array.GetUpperBounds(0) schreiben (das gilt übrigens natürlich nur für 1-dimensionale Arrays). Wie gesagt, normalerweise verwendet man keine nicht 0-basierten Arrays, weil sie überflüssig und unelegant sind.

    Ein Byte-Pointer wäre vom Typ System.Byte*, du aber hast System.Byte[*], ein Array von Byte-Pointer wäre System.Byte*[], würd' ich meinen.

    Gruß
    ~blaze~

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()

    Zeile Nr. 2 habe ich rausgeschmissen (die hat mich die ganze Zeit irritiert, stattdessen hat mir vorhin ein Cast in Array gefehlt, weil ich nicht wusste, was du vorhast), aber Zeilen 4,6 und 7 funktionieren 8o



    Ich danke dir!! Auch wenn ich nicht wirklich verstanden habe, was das Problem war. Es wurde quasi kein Byte()-Array sondern ein Array benutzt, deswegen kein Casting möglich, richtig? Woher wusste VS dann, dass es Byte() ist (im Überwachungsfenster)?
    Das Problem ist, dass Byte[*], also ein nicht 0-basiertes Byte-Array, kein Byte[], also kein 0-basiertes Byte-Array, ist. Der Unterschied wird gerade durch das * gekennzeichnet. Byte[*] ist somit kein Byte[], aber dafür noch System.Array, weswegen der Cast hinhaut. Die Darstellung von VS ist nicht korrekt, es gibt aber afaik keine syntaktisch korrekte Darstellung von Byte[*] in VB mehr. Dass die Werte korrekt entladen werden, ist wohl der zugrunde liegenden IEnumerable(Of T) zu verdanken, die Indizierung beginnt auch nicht beim Index des ersten Werts (in meinem Fall 2). Wenn man also von 0 in einer For-Each-Schleife hochzählt, würde das zu dem Ergebnis führen. Vmtl. würd der Typ rekonstruiert, indem auf die obj.GetType()-Methode zurückgegriffen wird (IsArray und so).

    Gruß
    ~blaze~
    Ich habe mir die Typen von beiden Arrays angeschaut, Basistyp ist bei beiden System.Array, deswegen klappt auch das Casting ins Array.



    Könnte ich quasi ins System.Byte[*] casten, würde es auch funktionieren. Nur leider weiß ich nicht, wie man es syntaktisch macht ;(

    Aber so geht es ja auch.

    Habe gerade versucht, erst Object ins Array zu konvertieren und dann vom Array in Byte-Array, bekomme aber die selbe Exception. Anscheinend hat es gespeichert, dass es kein nullbasiertes Array ist...

    ~blaze~ schrieb:

    Wie genau verwendest du denn das Byte-Array


    Ich benutze nur die Daten:

    VB.NET-Quellcode

    1. Dim ByteArr(11) As Byte
    2. Dim arr As Array = DirectCast(mdtpnviUnitStatus.RawValue, Array)
    3. 'Kopiere die Array-Daten in arr
    4. Dim bytes(arr.Length - 1) As Byte
    5. Buffer.BlockCopy(arr, 0, bytes, 0, arr.Length)
    6. If bytes.Length = 12 Then
    7. ByteArr(0) = bytes(0)
    8. ByteArr(3) = bytes(3)
    9. ByteArr(4) = bytes(4)
    10. For i = 7 To 11
    11. ByteArr(i) = bytes(i)
    12. Next
    13. End If
    14. Dim format_heat = CInt(nudUnitStatusH.Value * 200)
    15. Dim format_cool = CInt(nudUnitStatusC.Value * 200)
    16. ByteArr(1) = CByte(format_heat >> 8)
    17. ByteArr(2) = CByte(format_heat And &HFF)
    18. ByteArr(5) = CByte(format_cool >> 8)
    19. ByteArr(6) = CByte(format_cool And &HFF)
    20. mdtpnviUnitStatus.RawValue = ByteArr 'das ist dieses System.Byte[*]-Object, dem die neuen Werte zugewiesen werden
    Ok, bei der Größe ist es völlig egal, da rentiert es sich fast nicht, das noch anders zu verarbeiten. Wären das jetzt zehntausende Aufrufe oder mehrere Megabyte große Arrays, wäre es ggf. mal eine Überlegung gewesen.

    Übrigens wird bytes überflüssig, wenn du BlockCopy direkt auf ByteArr anwendest. Das funktioniert analog zu Array.Copy (zumindest für Bytes).

    Gruß
    ~blaze~

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()