LinkedList über mehrere Klassen

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von floxnet.

    LinkedList über mehrere Klassen

    Hallo,

    ich bin auf ein Problem mit einer LinkedLis() gestossen, bei welchem ich Euch um Rat fragen muss.

    Zum testen erstellte ich ein Konsolenprojekt mit einem Modul (ist eh automatisch enthalten) und dazu noch drei Klassen (Klasse1 - Klasse3).
    Die LinkedList ist Public im Modul deklariert, damit die Klassen darauf zugreifen und die Datensätze manipulieren können.

    Ich schaffe es aber nur, neue Datensätze anzufügen, müsste jedoch den letzten Knoten wiederverwenden und dort Daten einfügen.
    Aktuell werden dann, über drei Klassen und drei Variablen, natürlich drei Knoten erstellt - was aber Quark ist.

    (hoffe man kann mir folgen was ich versuche zu beschreiben)

    Hat da jemand eine Idee?

    Danke und viele Grüße,
    Floxnet
    Bilder
    • snippsel.PNG

      13,51 kB, 517×284, 88 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „floxnet“ ()

    Hallo EeranMaleasi,

    entschuldigung, dann lade ich die Source hoch.

    VB.NET-Quellcode

    1. Module Module1
    2. Public ListOfData As New LinkedList(Of Datalist)
    3. Public myData As Datalist
    4. Public Structure Datalist
    5. Dim Device As String
    6. Dim Value As String
    7. Dim DeviceType As String
    8. Dim DeviceAddress As String
    9. End Structure
    10. Sub Main()
    11. Dim cls1 As New Class1
    12. cls1.test1()
    13. Dim cls2 As New Class2
    14. cls2.test2()
    15. Dim cls3 As New Class3
    16. cls3.test3()
    17. For Each value In ListOfData
    18. '---> HInweis: nutze ich aktuell nicht, mir ging es nur um die Knoten in der Liste
    19. Next
    20. End Sub
    21. End Module


    VB.NET-Quellcode

    1. Public Class Class1
    2. Public Sub test1()
    3. Dim teststring As String = "Hund"
    4. myData.Value = teststring
    5. ListOfData.AddLast(myData)
    6. End Sub
    7. End Class


    VB.NET-Quellcode

    1. Public Class Class2
    2. Public Sub test2()
    3. 'Debug.Print(ListOfData(0).Device)
    4. Dim TestString As String = "Katze"
    5. myData.DeviceType = TestString
    6. ListOfData.AddLast(myData)
    7. End Sub
    8. End Class


    VB.NET-Quellcode

    1. Public Class Class3
    2. Public Sub test3()
    3. Dim TestString As String = "Maus"
    4. myData.Device = TestString
    5. ListOfData.AddLast(myData)
    6. End Sub
    7. End Class




    //EDIT//
    @EaranMaleasi,
    ist bereinigt. Sollte jetzt passen.

    Anhang vollständig bereinigt. ~EaranMaleasi
    Dateien

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

    Kapier ich nicht. Was willst Du denn erreichen? Um an den letzten Knoten ranzukommen, schreib z.B.:

    VB.NET-Quellcode

    1. Dim LastNode = ListOfData.Last
    Um an dessen Daten ranzukommen:

    VB.NET-Quellcode

    1. Dim DataOfLastNode = ListOfData.Last.Value

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo VaporiZed,

    Danke erstmal.

    Ah, mir geht es darum nicht in jeder Klasse einen neuen Knoten zu erstellen, sondern in Klasse2 zuerst mit dem aus Klasse1 zu arbeiten.
    Dort würde ich dann die weiteren Felder befüllen, welche leer sind.

    Also im wesentlichen einen Insert in Knoten(0), in Klasse2.

    Entschuldigung dafür, dass ich mich undeutlich ausgedrückt habe.
    Dein Code kann vorne und hinten nicht funktionieren.
    Du hast in deiner Anwendung nur ein myData-Objekt, und scheinst dasselbe mehrmals in die LinkedList stopfen zu wollen.

    floxnet schrieb:

    Ich schaffe es aber nur, neue Datensätze anzufügen, müsste jedoch den letzten Knoten wiederverwenden und dort Daten einfügen.
    Das liegt wohl daran, dass deine Datenklasse keine Class ist, sondern ein Structure.
    Structures kopieren sich immer, wenn man sie übergibt, und das macht sie gewissermassen "nicht-wiederverwendbar".



    (Und Datalist ist der denkbar schlechteste aller Namen für deine Datenklasse, denn es ist keine Liste, sondern ein Datensatz. Deine wirkliche Datalist heist ListOfData - das sagt tatsächlich aus wasses ist.)
    Structures kopieren sich immer, wenn man sie übergibt, und das macht sie gewissermassen "nicht-wiederverwendbar".


    Das erklärt so ziemlich alles, womit ich mich hier verzweifelt herumschlage... Dann bleibt's also dabei dass ich die LinkedList nur innerhalb einer Klasse nutzen kann.

    (Und Datalist ist der denkbar schlechteste aller Namen für deine Datenklasse, denn es ist keine Liste, sondern ein Datensatz. Deine wirkliche Datalist heist ListOfData - das sagt tatsächlich aus wasses ist.)



    Ja, mit den Benennungen habe ich es wirklich nicht.
    Korrekt müsste das so sein (wenn es um Geräteeigenschaften ginge) (danke wg ListOfData)

    VB.NET-Quellcode

    1. Public DeviceAttributes As New LinkedList(Of ListOfData)
    2. Public DeviceProperties As ListOfData
    3. Public Structure ListOfData
    4. Dim DeviceNr As String
    5. Dim DeviceValue As String
    6. Dim DeviceType As String
    7. Dim DeviceAddress As String
    8. End Structure
    Ich versteh bis jetzt nicht, wozu Du bei dieser Konstellation ne LinkedList brauchst. Was Du bisher machst: Du veränderst einen Datensatz. Dafür brauchst Du keine LinkedList, noch nicht mal überhaupt eine Art von Zusatzcontainer.
    Aber anscheinend kommen weitere Objekte erst später zur Liste dazu.

    floxnet schrieb:

    Dann bleibt's also dabei dass ich die LinkedList nur innerhalb einer Klasse nutzen kann.
    Nee. Du müsstest in Test1, Test2 und Test3 einfach nur anders arbeiten. Z.B. indem Du dort myData bearbeitest und erst nach den Aufrufen der genannten Sub myData zur LinkedList hinzufügst:

    VB.NET-Quellcode

    1. 'exemplarisch
    2. Public Class Class1
    3. Public Sub test1()
    4. myData.Value = "Hund"
    5. End Sub
    6. End Class


    VB.NET-Quellcode

    1. Sub Main()
    2. Dim cls1 As New Class1
    3. cls1.test1()
    4. Dim cls2 As New Class2
    5. cls2.test2()
    6. Dim cls3 As New Class3
    7. cls3.test3()
    8. ListOfData.AddLast(myData)
    9. myData.DeviceAddress = "Axolotl"
    10. ListOfData.AddLast(myData)
    11. End Sub

    Bilder
    • ProgramWithStructures.png

      26,94 kB, 1.002×195, 68 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    floxnet schrieb:

    Structures kopieren sich immer, wenn man sie übergibt, und das macht sie gewissermassen "nicht-wiederverwendbar".


    Dann bleibt's also dabei dass ich die LinkedList nur innerhalb einer Klasse nutzen kann.
    Wer hattn das gesagt? Das stimmt nicht, und so meinte ich das ganz bestimmt nicht.
    Sondern ich meinte, deine Datenklasse muss eine Class werden - nichts weiter:

    VB.NET-Quellcode

    1. Public Class ListOfData
    2. Dim DeviceNr As String
    3. Dim DeviceValue As String
    4. Dim DeviceType As String
    5. Dim DeviceAddress As String
    6. End Class
    (Das war ja auch die einzige Structure, von der die Rede sein konnte). Die Änderung zieht ein paar kleine weitere Änderungen nach sich, aber ist das Gleis in die richtige Richtung.
    Alles annere war vielleicht nicht hübsch, aber prinzipiell doch durchaus möglich.

    Was übrigens viel wichtiger ist: Visual Studio - Empfohlene Einstellungen - hast du das erledigt?
    Es gibt keinen Grund, das aufzuschieben - im Gegenteil: Jeder Aufschub macht den Umstieg u.U. schwerer - nämlich wenn bereits verdeckte Fehler in deim Code enthalten sind..

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

    Hallo VaporiZed und ErfinderDesRades,

    @VaporiZed,
    Das werde ich nachher ausprobieren. Heute habe ich etwas Zeit, auch wenn ich später arbeiten muss. An der Stelle erstmal Danke für den Input.

    @ErfinderDesRades
    Zwecks: "Was übrigens viel wichtiger ist: Visual Studio - Empfohlene Einstellungen - hast du das erledigt?"


    Nein. Ich habe es zwar mehrfach gelesen, wollte mich damit aber erst später befassen. Die Einstellungsempfehlung wird in wirklich vielen Threads erwähnt, darum werde ich das jetzt vorziehen.

    floxnet schrieb:

    darum werde ich das jetzt vorziehen.
    Das ist lobenswert.
    Vielleicht versuchst Du zunächst mal in einem Bildchen darzustellen, wie Deine Datenhierarchie aussieht, welche Klassen mit welchen Membern es gibt, von wo nach wo Daten hineingereicht werden und von wo sie wieder abgefragt werden.
    Wenn dieses Bildchen vorliegt, können wir es optimieren und Du wirst sehen, dass das ganze Problem wesentlich einfacher gestaltert werden kann.
    Das fängt an mit einer gemeinsamen Basisklasse Deiner Datenklassen wenn nicht gar nur einer Datenklasse.
    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!
    Hallo RodFromGermany,

    das kann ich machen sobald ich hier mit den empfohlenen Settings durch bin.

    Zu

    Visual Basic-Quellcode

    1. Option Strict On
    mal eine Frage:
    Angenommen ich aktiviere das in einem Projekt mit einer, durch late binding hinzugefügten ADODB Verbindung, dann erhalte ich die Meldung:
    Fehler 5 "Option Strict On" lässt spätes Binden nicht zu"


    1. Ist es eher empfohlen ein early binding zu nutzen?

    2. Ist "Option Stict" mit "Option Explicit" aus VBA identisch?

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

    @floxnet Spätes Binden bedeutet, dass da iwo eine Propeerty oder ein Result des Typs Object zurückkommt und dass dann zur Laufzeit nachgesehen wird, ob es eine Property dieses Namens überhaupt existiert; wen nicht, knallt es.
    In welchem Zusammenhang erhältst Du diesen Fehler?
    Für die üblichen Verdächtigen hat Microsoft Wrapper-Klassen vorbereitet. Wenn Du diese verwendest, ist Dein Problem gelöst.
    Von VBA hab ich keine Ahnung, aber bei früheren BASIC-Dialekten bedeutete Strict On, dass Variablen explizit deklariert werden mussten, da reichte ein Dim i1, um i1 als Variable vom Typ Variant zu erzeugen, Dim i2 As Integer stellte dann ein i2 vom Typ Integer bereit.
    Insofern ist das ein Unterschied zwischen VB.NET und alten BASIC-Dialekten.
    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!
    1. Nur, wenn es wirklich keine andere Möglichkeit gibt. Im Umgang mit Office kann es zwar nervig werden, aber da bin ich bisher immer von late binding und somit Strict Off weggekommen. Wie es bei der ADODB-Verbindung aussieht, weiß ich nicht.
    2. Nein, Option Explicit ist etwas anderes und auch explizit ( :P ) einstellbar: Projekteigenschaften -> Kompilieren:

    Die Auswirkung ist eine andere.
    Option Explicit zwingt zur Variablendeklaration durch Dim und Co. Option Strict zwingt zur Festlegung von Datentypen und korrekten Datentypverwendung. Umwandlungen werden nicht mehr durch den Compiler immer implizit vorgenommen. Nur wenn es datenverlustfrei möglich ist, z.B. Integer in Double. Andersrum geht es nicht (Verlust der Nachkommastellen).

    ##########

    Ich weiß zwar nicht, ob es zielführend ist, aber im MSDN-Artikel werden m.E. für das ADODB-Zeugsl explizite Datentypen angegeben.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    @RodFromGermany
    Alles klar, danke für die Erklärung.

    Zu deiner Frage:
    Die Anleitung zu den empfohlenen Einstellungen habe ich, um die Zusammenhänge besser verstehen zu können, in ein bestehendes Projekt übernommen.

    Kurz zu dem Projekt, dann ist es leichter nachvollziehbar:
    Ich habe eine Homematic-Anlage zur Steuerung der Behausung. Für diese Anlage gibt es Zusatzpakete, welche den Funktionsumfang erweitern.

    Für die Anlage habe ich das Zusatzpaket XML-API installiert (auf der Anlage selbst) damit eine Kommunikation via Alexa & Co möglich ist.

    Auf diese XML-Funktion greife ich nun in einem geschriebenen Projekt zu, damit die Anlage auch von einem WindowsPC gesteuert werden kann.
    (es ginge zwar auch per Sprache, nur wenn ich am PC sitze und mal Musik an habe, dann hört mich Alexa (die taube Nuss) mal wieder nicht, falls das Licht oder die Heizung ein/ausgeschaltet werden soll ... das ist mühsam und nervig, also dann eben über den PC fix angesteuert)

    OK, soweit zum Sinn des Projektes.

    In dem Projekt selbst gehe ich die XML-Struktur der Anlage durch und suche mir dort, zukünftig, die GeräteID's heraus. Momentan sind die ID'S noch fest hinterlegt, dass will ich aber ändern.
    Um einen besseren und strukturierten Überblick zu bekommen, schreibe ich derzeit die Geräteinformationen in eine DBF.

    Die Verbindungsinformationen für die DBF stehen im Quellcode und werden zur Laufzeit, erst an der benötigten Stelle, gebunden.

    Daher die Frage ob es besser ist ein Early Binding zu nutzen - weil es an der Stelle knallt :D
    Was ist ne DBF? Datenbankf…ussballmannschaft?
    Dass erst zur Laufzeit Daten reinkommen, hat ja nix mit dem Datentyp zu tun. Aber vielleicht steck ich nicht tief genug in dem Thema drin. Die MSDN-Themenverlinkung in Post#14 hast Du gesehen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @floxnet Keine Ahnung, ich kenne Alexa nicht. Hast Du ihre Telefonnummer? :thumbsup:
    Wenn es um das Auslesen von XML-Dateien geht, gibt es viele Wege, die nach Rom führen.
    Wie sieht denn die XML aus? Wer hat sie geschrieben?
    Welche DAtentypen sollen denn da generiert werden?
    Letzten Endes sind da Strings drinne, und es sollte immer eine Funktion geben, die den String in den richtigen Datentyp konvertiert: xxx.Parse(txt) oder xxx.TryParse(txt).
    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!
    @VaporiZednull
    dbf ist ein Datenbankformat, welches ich temporär nutze um die Daten aus der XML besser lesbar zu machen. Wäre nicht gut wenn, statt dem Licht, die Heizung an ginge :P

    Deinen Link habe ich gesehen. Danke.

    Ich nutze aktuell:

    VB.NET-Quellcode

    1. Dim DatabasePath As String = "C:\Users\floxnet\Desktop\"
    2. Dim DatabaseName As String = "DEVICELI.DBF"
    3. Dim adoConnection As Object
    4. adoConnection = CreateObject("ADODB.Connection")
    5. Dim adoRecordset As Object
    6. adoRecordset = CreateObject("ADODB.Recordset")
    7. Dim strSQL As String = Nothing
    8. Try
    9. With adoConnection
    10. .ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=C:\Users\floxnet\Desktop\;Extended Properties=dBase IV"
    11. .Open()
    12. strSQL = "INSERT INTO " & DatabaseName & " (ID, DEVICENAME, DEVICEID, DEVICEADDRESS, DEVICEVALUE) VALUES ( '" & i & "' ,'" & value.Device & "', '" & value.DeviceListSenderID & "', '" & value.DeviceListAddress & "', '" & value.Value & "')"
    13. adoRecordset.Open(strSQL, adoConnection)
    14. .Close()
    15. End With
    16. Catch ex As Exception
    17. End Try


    PS: ich weiss das "Value.value" echt bescheiden ist... aber ich habe mir noch keine Zeit genommen einen besseren Namen für meine LinkedList zu finden. Es ist einfach total verlockend das zu verwenden, was ad-hoc einfällt - auch wenn es sehr geistlos ist. Also bitte: nicht schimpfen :)


    @RodFromGermany

    Probier mal: 08932168 :D
    Ne, Spaß beiseite... Falls es dich interessiert was es mit der XML auf sich hat: homematic-inside.de/software/xml-api


    Die Datentypen konvertiere ich richtig. Das ist nicht das Problem.
    Hier mal ein Beispiel aus der DeviceList von meiner Zentrale:

    XML-Quellcode

    1. <deviceList>
    2. <device name="Aussenthermometer" address="OEQ1016670" ise_id="24113" interface="BidCos-RF" device_type="HM-WDS10-TH-O" ready_config="true">
    3. <channel name="Aussenthermometer:1" type="22" address="OEQ1016670:1" ise_id="24133" direction="SENDER" parent_device="24113" index="1" group_partner="" aes_available="false" transmission_mode="DEFAULT" visible="true" ready_config="true" operate="true"/>
    4. </device>
    5. <device name="Badezimmer" address="OEQ1950786" ise_id="23830" interface="BidCos-RF" device_type="HM-LC-Sw1PBU-FM" ready_config="true">
    6. <channel name="Badezimmer:1" type="26" address="OEQ1950786:1" ise_id="23863" direction="RECEIVER" parent_device="23830" index="1" group_partner="" aes_available="true" transmission_mode="DEFAULT" visible="true" ready_config="true" operate="true"/>
    7. </device>
    8. <device name="Balkonrollo" address="LEQ1169393" ise_id="2755" interface="BidCos-RF" device_type="HM-LC-Bl1PBU-FM" ready_config="true">
    9. <channel name="Balkonrollo:1" type="36" address="LEQ1169393:1" ise_id="2784" direction="RECEIVER" parent_device="2755" index="1" group_partner="" aes_available="true" transmission_mode="DEFAULT" visible="true" ready_config="true" operate="true"/>
    10. </device>
    11. <device name="Fensterkontakt Balkontüre" address="OEQ1979173" ise_id="26987" interface="BidCos-RF" device_type="HM-Sec-SCo" ready_config="true">
    12. <channel name="HM-Sec-SCo OEQ1979173:1" type="37" address="OEQ1979173:1" ise_id="27016" direction="SENDER" parent_device="26987" index="1" group_partner="" aes_available="true" transmission_mode="AES" visible="true" ready_config="true" operate="true"/>
    13. </device>
    14. <device name="Fensterkontakt Küche" address="OEQ1979155" ise_id="26932" interface="BidCos-RF" device_type="HM-Sec-SCo" ready_config="true">
    15. <channel name="HM-Sec-SCo OEQ1979155:1" type="37" address="OEQ1979155:1" ise_id="26961" direction="SENDER" parent_device="26932" index="1" group_partner="" aes_available="true" transmission_mode="AES" visible="true" ready_config="true" operate="true"/>
    16. </device>
    17. <device name="Fensterkontakt Wohnzimmer-Fenster" address="OEQ1979197" ise_id="27042" interface="BidCos-RF" device_type="HM-Sec-SCo" ready_config="true">
    18. <channel name="HM-Sec-SCo OEQ1979197:1" type="37" address="OEQ1979197:1" ise_id="27071" direction="SENDER" parent_device="27042" index="1" group_partner="" aes_available="true" transmission_mode="AES" visible="true" ready_config="true" operate="true"/>
    19. </device>
    20. <device name="Fensterrollo" address="LEQ1169661" ise_id="1650" interface="BidCos-RF" device_type="HM-LC-Bl1PBU-FM" ready_config="true">
    21. <channel name="Fensterrollo:1" type="36" address="LEQ1169661:1" ise_id="1679" direction="RECEIVER" parent_device="1650" index="1" group_partner="" aes_available="true" transmission_mode="DEFAULT" visible="true" ready_config="true" operate="true"/>
    22. </device>
    23. </deviceList>
    CreateObject eben …
    Importier mal über Projekteigenschaften -> Verweise -> [Hinzufügen…] -> |COM| die "Microsoft ActiveX DataObjects x.y Library"
    Dann kannst Du mit dem hier arbeiten:

    VB.NET-Quellcode

    1. Dim adoConnection = DirectCast(CreateObject("ADODB.Connection"), ADODB.Connection)
    2. Dim adoRecordset As ADODB.Recordset

    Man kann bestimmt auch das CreateObject loswerden, da VB6-Namespace, bin aber gerade zu faul, den Weg zu suchen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @floxnet OK. Bei der XML sehe ich absolut kein Problem.
    Die kannst Du wie auch immer in Instanzen einer Klasse Namens z.B. Device einlesen, Du hast dann für jedes Deiner Geräte eine Instanz, die die Daten aus der XML hält.
    Was mir jetzt hier iwo entfallen ist: Was ist denn Dein eigentliches Problem?
    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!