Dimensionierung eines Array mit Struktur

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Coldfire.

    Dimensionierung eines Array mit Struktur

    Hallo,
    ich versuche gerade ein Programm von VB6 nach VB.Net zu konvertieren.
    Die alte Version verwendete ein Array eines Benutzerdefinierten Typs um Daten strukturiert in einer Binärdatei abzulegen.

    Visual Basic-Quellcode

    1. Public Type TMischung
    2. Name1 As String * 23
    3. Name2 As String * 23
    4. Material(8) As String * 23
    5. Anteil(8) As Double
    6. KB_Breite(8) As Double 'neu ab v 0.6
    7. KB_Hoehe(8) As Double 'neu ab v 0.6
    8. Heizwert(8) As Double 'neu ab v 0.6
    9. CO2(8) As Double 'neu ab v 0.6
    10. End Type
    11. Public Mischung() As TMischung
    12. später dann, je nach größe der Datei Redim Mischung(x)


    Um auf diese Daten in den Dateien nun zugreifen zu können, müßte ich diese Struktur nachbilden.

    VB.NET-Quellcode

    1. <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
    2. Public Structure TMischung
    3. <VBFixedString(22)> Dim Name1 As String
    4. <VBFixedString(22)> Dim Name2 As Char
    5. <VBFixedArray(8 * 23)> Dim Material() As String
    6. <VBFixedArray(8)> Dim Anteil() As Double
    7. <VBFixedArray(8)> Dim KB_Breite() As Double 'neu ab v 0.6
    8. <VBFixedArray(8)> Dim KB_Hoehe() As Double 'neu ab v 0.6
    9. <VBFixedArray(8)> Dim Heizwert() As Double 'neu ab v 0.6
    10. <VBFixedArray(8)> Dim CO2() As Double 'neu ab v 0.6
    11. Sub New(ByVal x As Boolean)
    12. If x Then
    13. Name1 = String.Empty
    14. Name2 = String.Empty
    15. ReDim Material(8)
    16. For i0 As Integer = 0 To Material.GetLength(0) - 1
    17. Material(i0) = String.Empty
    18. Next
    19. ReDim Anteil(8)
    20. ReDim KB_Breite(8)
    21. ReDim KB_Hoehe(8)
    22. ReDim Heizwert(8)
    23. ReDim CO2(8)
    24. End If
    25. End Sub
    26. End Structure


    Wenn ich das Ganze mit

    VB.NET-Quellcode

    1. Public Mischung() As TMischung
    initialisiere und dann mit

    VB.NET-Quellcode

    1. ReDim Mischung(MischAnzFile - 1)
    in der Größe anpasse erhalte ich zwar mein Array, aber alle Bestandteile der Structur bleiben Nothing.

    ein

    VB.NET-Quellcode

    1. Public Mischung() As new TMischung
    läßt er leider nicht zu.

    Wie müßte die "richtige" Initialisierung aussehen?

    Vielen Dank für eure Tips.

    MisterCP schrieb:

    Wie müßte die "richtige" Initialisierung aussehen?
    Lass im Konstruktor den Zugriff auf den Parameter einfach weg:

    VB.NET-Quellcode

    1. Sub New(ByVal x As Boolean)
    2. Name1 = String.Empty
    3. Name2 = String.Empty
    4. ReDim Material(8)
    5. For i0 As Integer = 0 To Material.GetLength(0) - 1
    6. Material(i0) = String.Empty
    7. Next
    8. ReDim Anteil(8)
    9. ReDim KB_Breite(8)
    10. ReDim KB_Hoehe(8)
    11. ReDim Heizwert(8)
    12. ReDim CO2(8)
    13. End Sub

    @Haudruferzappeltnoch Das ist eine Struktur, da kann man keinen parameterlosen Konstruktor implementieren, der wird intern benötigt, wenn Du

    VB.NET-Quellcode

    1. Dim mischung As TMischung

    schreibst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    MisterCP schrieb:

    ganz so einfach ist es dann leider doch nicht

    Public Mischung() As New TMischung(True) ==> Arrays können nicht mit "New" deklariert werden.
    Doch is so einfach.
    Wenn du auch schreibst, was ich schreib Mischung as New TMischung(True) *
    nicht Mischung() as New TMischung(True), Mischung() ist ein Array

    Machst du z.B. Dim Mischung() = {New TMischung(True)}, aber im Moment ist mir nicht klar wofür du ein Array an TMischung brauchst. Daher denke ich dass du das auch gar nicht willst. Also guck erst mal bei * rein.
    @MisterCP Probier mal so:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
    4. Public Structure TMischung
    5. <VBFixedString(22)> Dim Name1 As String
    6. <VBFixedString(22)> Dim Name2 As Char
    7. <VBFixedArray(8 * 23)> Dim Material() As String
    8. <VBFixedArray(8)> Dim Anteil() As Double
    9. <VBFixedArray(8)> Dim KB_Breite() As Double 'neu ab v 0.6
    10. <VBFixedArray(8)> Dim KB_Hoehe() As Double 'neu ab v 0.6
    11. <VBFixedArray(8)> Dim Heizwert() As Double 'neu ab v 0.6
    12. <VBFixedArray(8)> Dim CO2() As Double 'neu ab v 0.6
    13. Sub New(x As Boolean)
    14. Name1 = String.Empty
    15. Name2 = New Char()
    16. ReDim Material(8)
    17. For i0 As Integer = 0 To Material.GetLength(0) - 1
    18. Material(i0) = String.Empty
    19. Next
    20. ReDim Anteil(8)
    21. ReDim KB_Breite(8)
    22. ReDim KB_Hoehe(8)
    23. ReDim Heizwert(8)
    24. ReDim CO2(8)
    25. End Sub
    26. End Structure
    27. Public Mischung() As TMischung
    28. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    29. ReDim Mischung(10)
    30. For i = 0 To 10
    31. Mischung(i) = New TMischung(True)
    32. Next
    33. End Sub
    34. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    ich würde empfehlen, dieses Dingens nicht als Structure anzulegen, sondern als Class.
    Structures sollten sich nur aus anderen Structures zusammensetzen.
    Weil wenn eine Struct an eine Variable oder Methode übergeben wird, wird sie komplett kopiert.
    Enthält sie nun ClassTypen, wie etwa Arrays, so werden da Referenzen kopiert.
    Somit hat man ein Dingens geschaffen, was sich teilweise wie ein Struct verhält, teilweise wie eine Class.
    Das wär mir iwie gruselig.
    Hallo,

    erst mal vielen Dank für eure Hinweise.

    @Haudrauferzappeltnoch: ich brauche tatsächlich das Array an Mischungen, denn in den Dateien liegen unterschiedlich viele dieser Mischungen hintereinander drin.
    Damit: Dim Mischung() = {New TMischung(True)}, funktioniniert es aber zum Glück.
    Dabei fällt mir ein, ich hätte zur Not auch jeweils nacheinander nur eine Mischung lesen können und die dann intern in eine Liste einfügen können.

    @ErfinderDesRades: Ich verstehe deinen Gedanken der sauberen Programmierung dabei. Allerdings muss ich nun mal an die Werte aus den alten Dateien ran. Also brauche ich ja irgendwie die Struktur zum lesen der Binär-Datei.
    (und ich habe sehr wenig Ahnung von Klassen :( )
    Vermutlich hast du von Klassen mehr Ahnung als von Structs.
    Weil Structs verhalten sich anders als man es normalerweise erwarten würde.
    Classes hingegen verhalten sich so, wie mans normal erwarten würde.

    Also hier RFGs Dingens als Class:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Class TMischung
    3. Public Name1 As String = ""
    4. Public Name2 As Char()
    5. Public Material(8) As String
    6. Public Anteil(8) As Double
    7. Public KB_Breite(8) As Double 'neu ab v 0.6
    8. Public KB_Hoehe(8) As Double 'neu ab v 0.6
    9. Public Heizwert(8) As Double 'neu ab v 0.6
    10. Public CO2(8) As Double 'neu ab v 0.6
    11. Sub New()
    12. For i0 As Integer = 0 To Material.Length - 1
    13. Material(i0) = ""
    14. Next
    15. End Sub
    16. End Class
    17. Public Mischung() As TMischung
    18. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    19. ReDim Mischung(10)
    20. For i = 0 To 10
    21. Mischung(i) = New TMischung(True)
    22. Next
    23. End Sub
    24. End Class

    für mich die Frage ist halt, wie du die Dateien einliest. Vermutlich mit irgendeiner einlesefunktion, die noch aus vb6-zeiten stammt.
    naja, dann ists zunächstmal tatsächlich am einfachsten, du lässt es, wie's bisher ist - sofern es nu funktioniert.

    Ansonsten müsste man neu überlegen, wie das Einlesen in .Net bewerkstelligen.

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