Von der Structure zur Class

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Von der Structure zur Class

    Lieber Schwarm, ich hätte da mal eine Grundlagenfrage für die ich im Web leider keine für mich Verständliche Antwort gefunden habe ;( .
    Aufgabe:
    Ich möchte gerne einen eigenen Datentyp mit Untergruppen erstellen, der sowohl normale Daten als auch Arrays enthält und dass über mindestens 2 Ebenen.
    Beispiel:

    VB.NET-Quellcode

    1. Auto.Farbe = "Schwarz"
    2. Auto.Ausstattung.Innen = "Comfort"
    3. Auto.Ausstattung.Aussen = {"Räder", "Nummernschild"}


    Ein Möglicher Ansatz ist: Structure

    VB.NET-Quellcode

    1. Public Auto As Fahrzeug
    2. Public Structure Fahrzeug
    3. Public Farbe As String
    4. Public AusstattungInnen As String
    5. Public AusstattungAussen() As String
    6. End Structure

    Wie ihr sehen könnt habe ich hier geschummelt. Es gibt nämlich nur eine Ebene, da ich noch nicht herausgefunden habe, wie man mittels Structure in die 2. Ebene kommt. Davon mal abgesehen wird einem ja quasi überall empfohlen das doch per Class zu realisieren, weil das so viel einfacher wäre. ECHT??? 8|

    Wie müsste ich eine Class aufbauen, damit ich zu dem oben gewünschten Ergebnis komme :?:
    Wer nichts weiß ist nicht Dumm sondern unwissend!
    VB.NET Neueinsteuger... aber natürlich immer in "Option Explicit" - sonst lernt man nit!

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim auto As New Fahrzeug()
    4. auto.Ausstattung.Innen.AddRange({"Aschenbecher", "Ledersitze"})
    5. auto.Ausstattung.Aussen.AddRange({"Sportauspuff", "Alufelgen"})
    6. auto.Farbe = "schwarz"
    7. End Sub
    8. End Class
    9. Public Class Fahrzeug
    10. Public Property Farbe As String
    11. Public Property Ausstattung As New Ausstattung()
    12. End Class
    13. Public Class Ausstattung
    14. Public Property Innen As New List(Of String)
    15. Public Property Aussen As New List(Of String)
    16. End Class


    Würde ich in Etwa so gestalten, falls es das ist, was Du mit 2. Ebene gemeint hast.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Grundsätzlich solltest du für alles eher Klassen verwenden. Es gibt Situationen wo eine Structure zu bevorzugen ist, aber im allgemeinen ist es nicht nötig diese zu verwenden.

    Du definierst die Klassen einfach als solche:

    VB.NET-Quellcode

    1. Public Class Fahrzeug
    2. Public Property Austattung as FahreugAustattung 'bin mir beim Property Syntax in vb.net nicht mehr ganz sicher
    3. End Class


    und eine zweite Klasse

    VB.NET-Quellcode

    1. Public Class FahrzeugAustattung
    2. public Property Innen as List(of Innenausstattung)
    3. public Property Außen as List(of Außenausstattung)
    4. End Class



    Die Klasse Fahrzeug muss halt nur wissen das es die Klasse FahrzeugAustattung gibt (also entweder im gleichen Namespace oder ein Import Statement).

    Grundsätzlich scheinst du generell noch Probleme zu haben mit der Datenmodellierung in Objekt Orientierter Programmierung.
    Innen und Außen sollten sicherlich keine Strings sein. Deshalb habe ich sie mal als List of Innenaustattung und Außenaustattung deklariert. In .NET solltest du nach Möglichkeit alles als Klassen und Objekte betrachten und dir vorher "modellieren" wie deine Klassen miteinander verbunden sind und welche Eigenschaften(Daten) sie haben und welche Funktionen (hier kommen dann im Normalfall Interfaces ins Spiel).

    Hoffe das hilft dir erstmal als Ansatz.

    LG
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo Mono,
    erstmal vielen Dank für deine schnelle Antwort. Werde ich auf jedenfall ausprobieren.
    Du hast mir da auch direkt neues Futter für die Suchmaschine gegeben. Leider finde ich den Einstieg nicht so einfach, da Beispiele oft entweder schon viel zu Komplex aufgebaut sind oder sich auf sehr detaillierte Problemstellungen beziehen.
    Vielleicht kann mir jemand mal einen Tipp geben für ein gutes Grundlagenbuch, Video Workshop oder Website. Vorzugsweise mit deutschen Erklärungen.
    Grüße
    Wer nichts weiß ist nicht Dumm sondern unwissend!
    VB.NET Neueinsteuger... aber natürlich immer in "Option Explicit" - sonst lernt man nit!
    Der Unterschied zwischen struct und class in .Net ist ganz einfach, dass die struct auf dem stack allokiert wird und die class auf dem heap. Damit kann man dann manche Optimierungen durchführen.
    In den meisten Fällen ist aber eine Klasse siinnvoller, da du mit diesen erstens mehr Features der OOP verwenden kannst und zweitens man sehr oft gar keine sinnvollen structs erzeugen kann:
    Du hast hier strings, welche auf dem heap allokiert werden und in der struct hättest du nur die referenzen auf dem stack, so ein großer Vorteil ist das nicht.
    Structs nimmt man eher für primitive Datentypen fester größe und baut diese auch wiederum aus primitiven Datentypen auf. Am meisten wirst du das bei mathematischen Typen sehen wie Vector/Matrix u.ä. das arbeiten mit diesen ist auf dem Stack oftmals wesentlich performanter, da diese keine übergroßen Datenmengen enthalten.

    Sobald man außerdem ein struct in einer List/Array/o.ä. verwendet werden die structs auch Heap-allocated, was den ganzen Vorteil wieder verliert.

    In den meisten Fällen wirst du also keine struct brauchen...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    Der Unterschied zwischen struct und class in .Net ist ganz einfach, dass die struct auf dem stack allokiert wird und die class auf dem heap.
    dazu 2 Anmerkungen
    1. naja, wenn du das "einfach" findest....
    2. Das wesentliche fehlt: Structs sind WerteTypen, und class sind ReferenzTypen
    Bei ReferenzTypen wird bei Zuweisung eines Objekts die Referenz auf das Objekt übergeben. Ändert der Zuweisungs-Empfänger Eigenschaften des Objekts, so sind die Eigenschaften auch beim Aufrufer geändert - denn es gibt nur ein Objekt, und beide: Aufrufer und Zuweisungs-Empfänger haben eine Referenz darauf.

    Bei Werttypen wird bei Zuweisung eine Kopie des Objekts übergeben. Ändert der Zuweisungs-Empfänger Eigenschaften seines Objekts, so bleibt des Aufrufers Objekt unverändert - weil es sind ja 2 verschiedene Objekte.

    Wurde nu schon mehrfach gesagt (nur ich gebe eine hofflich nachvollziehbare Begründung): In den meisten Fällen ist Class das Mittel der Wahl.
    Zum Beispiel mittm Auto und seiner Ausstattung: Kann ja sein, man übergibt ein Auto an eine Methode, die es ausstatten soll.
    Da fährt man voll vor die Wand, wenn Auto ein Struct ist, weil die Ausstattungs-Methode wird dann nur eine Kopie des Autos ausstatten - das Original beim Aufrufer bleibt davon unberührt - und der Programmierer wundert sich. ?(

    Frage an @Darkscale: Kannst du meine Begründung nachvollziehen?

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

    1. ja das finde ich einfach.
    2. ich habe von primitiven typen gesprochen, welche außerdem alle wertetypen sind.
    Aber du hast Recht darauf hätte man näher eingehen können. Wobei ich das nicht unbedingt für das wesentliche halte.

    ErfinderDesRades schrieb:

    Da fährt man voll vor die Wand, wenn Auto ein Struct ist, weil die Ausstattungs-Methode wird nur eine Kopie des Autos ausstatten - das Original bleibt davon unberührt - und der Programmi

    Leider falsch, da die Ausstattung als List(Of deklariert ist und somit ein Referenztyp, wenn die struct kopiert wird, wird nur die Referenz auf diese List(Ofs kopiert, damit zeigen beide structs, obwohl es eine Kopie ist auf diesselbe List(Of und wenn diese verändert wird, geschieht dies somit natürlich aus der Sicht der structs auch für beide.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    @jvbsl und @ErfinderDesRades
    Mir sind diese Unterschiede bekannt, ich wollte nur bewusst darauf erstmal gar nicht eingehen da ich davon ausgehe das man dann immer weiter erklären muss.
    (was ist heap, stack, referenztypen, wertetypen etc). Dies könnte den TE leicht überfordern und führt nur zu unnötigen Detaildiskussion wie ja zu sehen.


    @Darkscale
    Ich kenn leider kein wirklich gutes Tutorial empfehlen aber ich weiß das der @ErfinderDesRades sehr viele deutsche Tutorials veröffentlicht hat zum Einstieg in die Programmierung mit .NET.
    Das fängt an mit Einstellungen der IDE, Grundlagen und Begriffe bis zu Grundlagen der Datenmodellierung.
    Ich bin um ehrlich zu sein zu faul die Links zu suchen. Aber vll findest du die ja selber oder jemand schreibt sie dir hier rein.
    Wenn du konkrete Fragen hast dann stell sie einfach :)

    LG
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo nochmal, vielen Dank für die vielen Beiträge. Ich denke, dass sicher noch mehr diese Fragen quälen.
    Mono hat leider recht. Als Einstiger ist man mit den ganzen begrifflichkeiten schnell überfordert. Ich noch sehr wenig mit begriffen wie heap, stack, referenztypen usw. anfangen. Was auch der Grund ist, warum mir aktuell noch die "MSDN Library" nur bedingt weiterhilft.

    Ich kann ja mal von dem Theoretischen Beispiel mein ganz konkretes Schildern, Falls da Interesse besteht, sollte ich das aber vielleicht in einem ExtraFred auf machen, da sicherlich die meißten Coder hier im günstigsten Fall verwundert sind.

    Zum Hintergrund:
    Ich habe 10 Spiele, für die je diverse unterschiedliche Maps,Mods oder auch zusätzliche Software wie Karteneditoren existieren. Im Moment nutze ich daher einen ganzen Satz an Variablen, die ich entsprechend welches Spiel ausgewählt ist ersetze.
    Hier meine aktuellen Variablen:

    VB.NET-Quellcode

    1. ​Public Game As SpielParameter
    2. Public Structure SpielParameter
    3. Public Spiel As String 'Spielkürzel ""
    4. Public Pos As Integer 'Position des Covers auf dem Launcher
    5. Public Flag As Boolean 'Ist das Spiel Installiert?
    6. Public InstallDir As String 'Pfad zum Ort der Hauptspielinstallation: "WOW6432Node\EA Games\Mein Spiel"
    7. Public Inst() As String 'Pfad zur Installationsdatei für das Hauptspiel
    8. Public MapsExist As Boolean 'Gibt es Maps?
    9. Public MapsFile() As String 'Pfad zum Installationsort für MAPs
    10. Public MapsPath() As String 'sfx.RAR Ja oder nein
    11. Public ModsExist As Boolean 'Gibt es MODs?
    12. Public ModsFile() As String 'Pfad zum Installationsort für MODs
    13. Public ModsPath() As String 'sfx.RAR Ja oder nein
    14. Public ExtrasExist As Boolean 'Gibt es Extras?
    15. Public ExtrasFile() As String 'Pfad zum Installationsort für Extras
    16. Public ExtrasPath() As String 'sfx.RAR Ja oder nein
    17. Public LinkNameTest As ArrayList 'Name der Verknüpfung
    18. Public LinkName() As String
    19. Public LinkFile() As String 'Datei von der eine Verknüpfung erstellt werden soll
    20. Public LinkParam() As String 'Fügt einen Parameter zur File hinzu
    21. Public LinkIcon() As String 'Pfad zu dem Icon für die Verknüpfung
    22. Public InfoGame As String 'Name des Spiels
    23. Public InfoMaps As String 'Details über die Maps
    24. Public InfoMods As String 'Details über die Mods
    25. Public InfoExtras As String 'Details über die Extras
    26. End Structure
    27. Sub Spieldeklaration(IntGame As String)
    28. Select Case IntGame
    29. Case "CNC_TD"
    30. Reg = "Software\WOW6432Node\EA Games\CNC and The Covert Operations"
    31. If CheckRegPath("LM", Reg) = True Then Game.Flag = True 'Prüft den Pfad in den das Spiel installiert wurde und speichert diesen in der Variable Game.InstallDir
    32. Game.Pos = 1
    33. Game.Inst(0) = "Install TD.exe /NOICONS"
    34. Game.MapsExist = False
    35. Game.ModsExist = False
    36. Game.ExtrasExist = True
    37. ReDim Game.MapsFile(0 To 0)
    38. ReDim Game.MapsPath(0 To 0)
    39. Game.MapsFile = {Nothing}
    40. Game.MapsPath = {Nothing}
    41. ReDim Game.ModsFile(0 To 0)
    42. ReDim Game.ModsPath(0 To 0)
    43. Game.ModsFile = {Nothing}
    44. Game.ModsPath = {Nothing}
    45. ReDim Game.ExtrasFile(0 To 0)
    46. ReDim Game.ExtrasPath(0 To 0)
    47. Game.ExtrasFile = {"MapEditor.exe"}
    48. Game.ExtrasPath = {Game.InstallDir}
    49. ReDim Game.LinkName(0 To 2)
    50. ReDim Game.LinkFile(0 To 2)
    51. ReDim Game.LinkIcon(0 To 2)
    52. Game.LinkName = {"C&C - Der Tiberiumkonflikt", "C&C - Der Tiberiumkonflikt Config", "C&C - Der Tiberiumkonflikt WorldBuilder"}
    53. Game.LinkFile = {"C&C95.bat", "CCConfig.exe", "CCWMAP.EXE"}
    54. Game.LinkIcon = {"C&C95.ico", "CCConfig.ico", "CCWMAP.EXE"}
    55. 'InfoBox
    56. Game.InfoGame = "C&&C - Der Tiberiumkonflikt (1995) - Der Ausnahmezustand (1996)"
    57. Game.InfoMaps = ""
    58. Game.InfoMods = ""
    59. Game.InfoExtras = "WorldBuilder"
    60. Call BtnLayout(2)
    61. End Select
    62. End Sub


    Das Ganze Funktioniert zwar schon, aber ich habe noch einiges auf meiner Todo Liste:
    1. Erst wollte ich die ReDim funktion durch eine ArrayList ersetzen. Bei meiner Recherche bin ich dann auf die Empfehlung mit der Class gestoßen.
    FRAGE: Ist das für meinen Zweck Sinnvoll?
    2. Ich würde gerne das Programm soweit umbauen, dass man die Parameter aus Spieledeklaration​ in eine cfg oder ini oder ever auslagern kann. Damit falls mal was dazu kommt oder ich etwas aus der Liste entfernen will ich nicht in den Code gehen muss.
    Das übersteigt im Moment noch meine Fähigkeiten bei weitem. Ist aber mein Ziel.
    Wer nichts weiß ist nicht Dumm sondern unwissend!
    VB.NET Neueinsteuger... aber natürlich immer in "Option Explicit" - sonst lernt man nit!

    Darkscale schrieb:

    1. Erst wollte ich die ReDim funktion durch eine ArrayList ersetzen. Bei meiner Recherche bin ich dann auf die Empfehlung mit der Class gestoßen.
    FRAGE: Ist das für meinen Zweck Sinnvoll?
    2. Ich würde gerne das Programm soweit umbauen, dass man die Parameter aus Spieledeklaration in eine cfg oder ini oder ever auslagern kann. Damit falls mal was dazu kommt oder ich etwas aus der Liste entfernen will ich nicht in den Code gehen muss.
    1) ArrayList sollte man nie mehr verwenden. 2005 sind generische Listen eingeführt worden - ArrayList ist seither Gerümpel, und nur wg Abwärtskompatiblität noch vorhanden.
    Also schreib

    VB.NET-Quellcode

    1. ' statt: Public ModsFile() As String
    2. 'schreib
    3. Public ModsFile As New List(Of String)
    Feddich - Redim rausschmeissen.
    2) dafür musst du programmieren lernen. ZB alles hier gesagte (Struct, Class, generische Listen, ...) musst du inhaltlich verstehen, und noch vieles mehr.
    ZB ist Public ModsFile As New List(Of String) auch Grütze, weil du musst DatenKlassen schaffen, und von denen evtl. Listen anlegen - nicht so dumme String-Lists.
    Bei dem, was du dir vorgenommen hast, wirds sogar noch weiter gehen, dass du lernen musst, mit typisiertem Dataset umzugehen.
    Das ist eine Technik, bei der ist Laden, Speichern, Ändern, Löschen, Zufügen, Sortieren,... bereits fertig eingebaut. Und ungefähr 50% davon brauchst du, und es wäre ziemlich unklug, das alles selbst erfinden zu wollen.

    wie dem auch sei - hier mein "Lehrplan" für Leuts, die Datenverarbeitung programmieren wollen:
    Datenverarbeitungs-Vorraussetzungen