index einer List(of cls)

  • VB.NET

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

    index einer List(of cls)

    Hallo die Damen und Herren,

    ich versuche gerade eine (für mich) etwas größere Klasse zu bauen. Die Klasse soll so etwas ähnliches wie einen Kommisionierungsauftrag darstellen. In diesem Auftrag gibt es eine Property Paletten vom Typ clsPaletten.

    clsPaletten erbt von List(of clsPalette), diese clsPalette ist gekapselt mit in der Klasse clsPaletten und clsPaletten ist gekapselt in der clsAuftrag

    clsPalette hat eine Eigenschaft vom Typ clsVerpackungen, diese erbt auch von List(of clsVerpackung). clsVerpackung ist gekapselt innerhalb der clsVerpackungen.

    clsVerpackung hat eine Eigenschaft vom Typ clsKassetten, diese erbt auch von List(of clsKassette). clsKassette ist gekapselt innerhalb der clsVerpackungen.

    Es sollen also pro Auftrag x Paletten hinzugefügt werden können. Jede Palette hat x Verpackungen und jede Verpackung hat x Kassetten.

    Das ganze sieht dann ungefähr so aus:

    VB.NET-Quellcode

    1. Public Class clsAuftrag
    2. Dim _IDSQL As Integer
    3. Public ReadOnly Property IDSQL As Integer
    4. GetReturn _IDSQL
    5. End Get
    6. End Property
    7. Private Shared _Paletten As New clsPaletten
    8. Public ReadOnly Property Paletten As clsPaletten
    9. GetReturn _Paletten
    10. End Get
    11. End Property
    12. Public Class clsPalettenInherits List(Of clsPalette)
    13. Public Overloads Sub Add(ByVal Nr As Integer)MyBase.Add(New clsPalette(Nr))
    14. End Sub
    15. Public Class clsPalette
    16. Private Shared _Nr As Integer
    17. Public ReadOnly Property Nr As Integer
    18. GetReturn _Nr
    19. End Get
    20. End Property
    21. Private Shared _Verpackungen As clsVerpackungen
    22. Public ReadOnly Property Verpackungen As clsVerpackungen
    23. GetReturn _Verpackungen
    24. End Get
    25. End PropertyPublic Sub New(ByVal NewNr As Integer)
    26. _Nr = NewNr
    27. _Verpackungen = New clsVerpackungen
    28. End Sub
    29. Public Class clsVerpackungenInherits List(Of clsVerpackung)
    30. Public Overloads Sub Add(ByVal Nr As Integer)Dim NewVerpackung As New clsVerpackung(Nr)
    31. MyBase.Add(NewVerpackung)
    32. End Sub
    33. Public Class clsVerpackung
    34. Private Shared _ID As Long
    35. Public ReadOnly Property ID As Long
    36. GetReturn _ID
    37. End Get
    38. End Property
    39. Private Shared _Containernummer As Integer
    40. Public ReadOnly Property Containernummer As Integer
    41. GetReturn _Containernummer
    42. End Get
    43. End Property
    44. Private Shared _Kassetten As clsKassetten
    45. Public ReadOnly Property Kassetten As clsKassetten
    46. GetReturn _Kassetten
    47. End Get
    48. End PropertyPublic Sub New(ByVal Nr As Integer)
    49. _Containernummer = Nr
    50. _Kassetten = New clsKassetten
    51. End Sub
    52. Public Class clsKassetten
    53. Inherits List(Of clsKassette)
    54. Public Overloads Sub Add(ByVal Gewicht As Double)
    55. MyBase.Add(New clsKassette(Gewicht, MyBase.Count + 1))
    56. End Sub
    57. Public Class clsKassette
    58. Private Shared _ID As Long
    59. Public ReadOnly Property ID As Long
    60. GetReturn _ID
    61. End Get
    62. End Property
    63. Private Shared _Nr As Integer
    64. Public ReadOnly Property Nr As Integer
    65. GetReturn _Nr
    66. End Get
    67. End Property
    68. Private Shared _Timestamp As DateTime
    69. Public ReadOnly Property Timestamp As DateTime
    70. GetReturn _Timestamp
    71. End Get
    72. End Property
    73. Private Shared _Gewicht As Double
    74. Public ReadOnly Property Gewicht As Double
    75. GetReturn _Gewicht
    76. End Get
    77. End Property
    78. Private Shared _Anzahl As Integer
    79. Public ReadOnly Property Anzahl As Integer
    80. GetReturn _Anzahl
    81. End Get
    82. End PropertyPublic Sub New(ByVal Gewicht As Double, ByVal Nr As Integer)
    83. _Timestamp = Now
    84. _Gewicht = (Gewicht - _Kassettengewicht) / _AnzdhEinzelGewicht
    85. _Nr = Nr
    86. End Sub
    87. End Class
    88. End Class
    89. End Class
    90. End Class
    91. End Class
    92. End ClassEnd Class

    Die abfrage einer Kassette müsste ich dann später so machen:

    VB.NET-Quellcode

    1. Anzahl = Auftrag.Paletten(indexP).Verpackungen(indexV).Kassetten(indexK).Anzahl

    Gibt es da eine Möglichkeit statt über den "index" mit einer anderen variable auf die Auflistungselemente zuzugreifen? Sowas wie:

    VB.NET-Quellcode

    1. Auftrag.Paletten(Nr).Verpackungen(Verpackungsnummer).Kasetten(Nr).Anzahl

    Also statt den index der List(of T) eine Property der gelisteten Klassen verwenden?
    Ich hoffe man versteht was ich meine :)


    MfG
    Befree

    Befree schrieb:

    VB.NET-Quellcode

    1. End Class
    2. End Class
    3. End Class
    4. End Class
    5. End Class
    6. End Class
    7. End Class
    7 Klassen ineinander geschachtelt?
    Das ist aber der oberallergröbste Designfehler, der mit in den letzten nnn untergekommen ist.
    Vereinzele die mal und dann sehen wir weiter.
    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!
    Dein Code ist völlig "unformatiert". Darum wusel ich mich da jetzt nicht durch.

    Aber ich ahne dennoch was du willst, darum hier stellvertretend für alle deine von List(of T) abgeleiteten Klassen ein Beispiel:

    VB.NET-Quellcode

    1. Default Public Overloads ReadOnly Property Item(ByVal Verpackungsnr As Integer) As clsVerpackung
    2. Get
    3. 'Hier der Code um aus der Liste das korrekte Item
    4. 'anhand des Funktionsparameters auszuwählen
    5. '...
    6. End Get
    7. End Property


    Analog dazu das gleiche in deinen anderen List(of T)-Klassen.

    Das "Default"-Schlüsselwort sorgt dafür, dass du per Indexer () auf die Elemente der Liste zugreifen kannst, ohne den Namen der Eigenschaft mit angeben zu müssen - und funktioniert natürlich nur für eine Eigesnchaft pro Klasse. List(of T) hat bereits eine Item-Eigenschaft, die als Default markiert ist, sie wird also im Grunde nur mit dem was du eigentlich haben willst, überschrieben.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.

    Befree schrieb:

    Was genau spricht dagegen die Klassen so zu Kapseln?
    Solch Konstrukt kannst Du nicht pflegen, es ist einfach Ranz.
    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!
    NA dann hier ein neuer Versuch. Ich habe die Änderungen mit der "DefaultPublicOverloadsReadOnlyProperty Item" mal schon mit rein.

    VB.NET-Quellcode

    1. Public Class clsVerpackungen
    2. Inherits List(Of clsVerpackung)
    3. Default Public Overloads ReadOnly Property Item(ByVal Nr As Integer) As clsVerpackung
    4. Get
    5. Return MyBase.Find(Function(VP As clsVerpackung)
    6. Return VP.Nr = Nr
    7. End Function)
    8. End Get
    9. End Property
    10. Public Overloads Sub Add(ByVal Nr As Integer)
    11. Dim NewVerpackung As New clsVerpackung(Nr)
    12. MyBase.Add(NewVerpackung)
    13. End Sub
    14. Public Class clsVerpackung
    15. Private Shared _ID As Long
    16. Public ReadOnly Property ID As Long
    17. Get
    18. Return _ID
    19. End Get
    20. End Property
    21. Private Shared _Nr As Integer
    22. Public ReadOnly Property Nr As Integer
    23. Get
    24. Return _Nr
    25. End Get
    26. End Property
    27. Private Shared _Prüfer As String
    28. Public ReadOnly Property Prüfer As String
    29. Get
    30. Return _Prüfer
    31. End Get
    32. End Property
    33. Private Shared _Kassetten As clsKassetten
    34. Public ReadOnly Property Kassetten As clsKassetten
    35. Get
    36. Return _Kassetten
    37. End Get
    38. End Property
    39. Public Sub New(ByVal Nr As Integer)
    40. _Nr = Nr
    41. _Prüfer = ""
    42. _Kassetten = New clsKassetten
    43. End Sub
    44. End Class
    45. End Class


    Um nochmal auf den Ranz zu kommen, es geht also nur um Lesbarkeit und solche Dinge warum man es nicht kapseln sollte?

    Befree schrieb:

    Lesbarkeit

    RodFromGermany schrieb:

    Solch Konstrukt kannst Du nicht pflegen
    Glaubst Du, Du fängst heute ein Programm an, ümorgen ist es fertig und bleibt für alle Zeit so?
    Iwann fängst Du mit Erweiterungen, Änderungen allgemein an, und dann musst Du Deinen Quellcode noch verstehen.
    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!

    RodFromGermany schrieb:

    Iwann fängst Du mit Erweiterungen, Änderungen allgemein an, und dann musst Du Deinen Quellcode noch verstehen.

    Und spätestens wenn man anfängt, seine Programmiertechnik in einem Projekt anzuwenden, das in einem Team realisiert wird, wird es essentiell wichtig, auf Lesbarkeit und Nachvollziehbarkeit zu achten. Und Kommentare nicht vergessen.
    Aber wie Rod bereits schrieb: In der Regel willst du nach einer gewissen Zeit (ein paar Tage, ein paar Wochen, ein paar Jahre womöglich) Änderungen oder Ergänzungen an deinem Programm vornehmen - und wenn dann nicht sauber gearbeitet und dokumentiert wurde, kannst du im Grunde gleich wieder von vorne anfangen.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.

    Befree schrieb:

    es geht also nur um Lesbarkeit
    Essis logisch einfach falsch, Vepackung in Verpackungsliste einzuschachteln (es ist keine Kapselung, sondern eine Schachtelung)
    Eine VerpackungsListe ist was ganz anneres als eine Verpackung - da gibts keine Kohärenz (so heisst das glaub).
    Also soll das auch in ganz unabhängigen Klassen gecodet sein.

    Also eine Garage ist ja auch kein Auto, und hat konstruktiv absoltu ühaupt nix damit zu tun.

    Also die Elemente einer Garage mögen ja Autos sein, aber trotzdem ist Garage etwas total anneres als ein Auto.
    Schachtelung von Klassen macht eigentlich nur in einem Fall Sinn, und zwar wenn die geschachtelte Klasse privat ist, also nur die enthaltende Klasse auf sie zugreifen kann. Und das macht man wiederum nur dann, wenn die geschachtelte Klasse der enthaltenden Klasse bei irgend was hilft (Strukturierung o.ä.), aber nach außen hin keinen Verwendungszweck hat. Sogar die MS-Guidelines sagen, man solle geschachtelte Klassen vermeiden (und ich predige diese Guidelines ja rauf und runter, wie manche wissen ;) ).
    Um solche Klassen wie oben beschrieben als zueinander zugehörig zu kennzeichnen, steckt man sie beide in den gleichen Namespace, nichts anderes.