Variableninhalt (Text) als Varaible (Name = Text) nutzen - bekannte Variablen dynamisch ansprechen

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

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von a.b_om.

    Variableninhalt (Text) als Varaible (Name = Text) nutzen - bekannte Variablen dynamisch ansprechen

    Moin,

    ganz blöde Frage.
    Ich lese einen Wert aus der Registry aus - soweit alles gut.
    Nun ist der Wert "xyz" in der Variable "RegistryWert".
    Es gibt 3 weitere Varaiblen: xyz, xyy, xzz, alle mit unterschiedlichem Inhalt (alle als List(Of T))

    Aufgrund des ausgelesenen Wertes will ich nun mit der entsprechenden Variable fortfahren.
    Da ich ja aber nicht weiß was ausgelesen wurde, nur, dass es einer der drei Variablennamen sein kann, will ich den Inhalt als Variablennamen nutzen/die Variable entsprechend Inhalt ansprechen. (Aber ich bin gerade zu blöd dafür)

    Ich habe es versucht über CTYPE(RegistryWert.toString, Object) aber das klappt nicht.

    VB.NET-Quellcode

    1. '(um zu testen zählen wie viele Werte in List (Of T) stehen)
    2. MsgBox((RegistryWert.toString).Count) 'Ergebnis 3 (weil 3 Buchstaben)
    3. 'soll ja übersetzt heißen weil toString = xyz
    4. MsgBox(xyz.Count) 'Ergebnis 5 (weil 5 Einträge)

    Ich hoffe es wird klar was ich will.

    Warum ich es will: Ich weiß zwar was aus der Registry raus kommt, aber ich will Code einsparen und könnte so aus 5-6 verschiedenen Schleifen einfach eine machen, da ich die entsprechende Variable "dynamisch" ansprechen kann
    Ja ich löse das Problem momentan am Anfang mit

    VB.NET-Quellcode

    1. If RegistryWert = "xyz" THEN
    2. '... eine ganze Menge Vorgänge und FOR Schleifen und weitere IF Bedingungen
    3. ELSEIF RegistryWert = "xzz" THEN
    4. '... eine ganze Menge Vorgänge und FOR Schleifen und weitere IF Bedingungen ABER DIE SELBEN WIE OBEN
    5. END IF

    Allerdings muss ich das so für jeden etwaigen Wert einzeln machen. Heißt also leider auch, dass alles in der IF sich im Prinzip wiederholt. Daher ist der Code 60 Zeilen und mehr lang, müsste aber nur 10 Zeilen lang sein. UND (wichtig) wenn mal weitere Inhalte aus der Registry dazu kommen, muss ich bloß ein neues List(Of T) erstellen und nicht nochmal mindestens 10 Zeilen Code dazu schreiben - Flexibilität und Erweiterungsfähigkeit ist mein Stichwort.
    HäWasWieWoWer?
    Von welchem Typ ist denn der Registry-Eintrag? Zeichenkette, mehrteilige Zeichenkette, erweiterbare Zeichenkette, was anderes?
    Nenn mal bitte Beispielinhalte für xyz, xzz, xyy (Heißen die Schlüssel wirklich so? Ich hoffe nicht. Aber für das Lösen des Problems ist das ein wenig verwirrend.)
    CTYPE(RegistryWert.toString, Object) Dafuq? Was erhoffst Du Dir davon?
    MsgBox: Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden.
    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.
    @Eierlein

    Lies mal Post 3 GANZ genau durch.

    Falls du keine Lust hast, hier die Lösung:
    Spoiler anzeigen
    Er möchte keine Langen Abfragen. Er möchte nicht 60 mal abfragen, alles mit Ifs und ElseIfs. Er möchte wenig code. eine Schleife ist die beste Methode.
    @ThomasG82
    Wie wäre es wenn du deine List(Of T)s in ein Dictionary(Of String, List(Of T)) packst.

    VB.NET-Quellcode

    1. 'PseudoCode
    2. Dim dic As New Dictionary(Of String, List(Of T))
    3. Dim xyz As List(Of T)
    4. Dim xyy As List(Of T)
    5. Dim xzz As List(Of T)
    6. dic.Add("xyz", xyz)
    7. dic.Add("xyy", xyy)
    8. dic.Add("xzz", xzz)
    9. Dim RegistryWert As String = "xyz"
    10. Dim myList As New List(Of T)
    11. myList = dic(RegistryWert)
    12. '... eine ganze Menge Vorgänge und FOR Schleifen und weitere IF Bedingungen
    @ThomasG82 Erkläre mal anhand von einem Daten-Beispiel, nicht aber Code, was da passieren soll.
    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!
    @VaporiZed - nein die Variablen heißen im Realfall natürlich nicht so :) das war jetzt einfach nur ganz einfach um es zu erklären.
    Ach so - das MsgBox benutze ich nicht - das war jetzt hier nur als Erklärung eingefügt worden. Ja ich beachte VB.NET ;)
    @HenryV - ja muss ich mal genau überlegen ob das gehen würde - melde mich deswegen nochmal.

    @RodFromGermany: Also ich versuche es mal (hab ja immer ein Problem mit einfach erklären)

    Ich lese einen Wert aus der Registry von Windows aus. Was dabei herauskommt, weiß ich, da es nur 35 verschiedene Möglichkeiten gibt. Für alle 35 Möglichkeiten habe ich eine Variable [List (Of String)], in welcher ich die entsprechenden Werte der jeweiligen Möglichkeit hinterlegt habe. Diese Werte benötige ich später in meinem Programm.
    Um nun nicht 35 mal WENN-DANN-SONST zu fragen will ich den Wert, den ich aus der Registry erhalte, Verwenden um damit die richtige Variable anzusprechen.
    Im Bild sieht man es - Der Inhalt der RegistryVariable soll weitergenutzt werden als Variable (diese existiert auch und hat Inhalt).

    Somit umgehe ich die 35 WENN-DANN Abfragen und VON-BIS Schleifen. Ich kann alles einmal schreiben und so einfach prüfen.
    Sprich der Variableninhalt soll als Name genutzt werden, denn der Name ist bekannt.

    Verständlich? ?(
    Bilder
    • Anmerkung 2019-12-11 171635.png

      39,92 kB, 775×165, 79 mal angesehen

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

    @ThomasG82 Du kannst ein Dictionary(Of String, String) verwsenden und mit Deinen Zieldaten befüllen.
    Mit Dim value = dict(reg) kommst Du mit einem Einzeiler an Deinen Wert.
    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!
    Du meinst also, dass ich aufgrund dessen was ich als Wert habe ein Dictionary erstelle und entsprechend hinein kopiere?
    Also eine "Zwischenvariable" kreiere?

    Jetzt hab ich es kapiert - du meinst - alle einzelnen List (Of String) aufgeben und alles zusammen in ein komplettes Dictionary (Of String, String) legen.
    Ja ist auch eine Variante und glaub ich auch am einfachsten beim späteren hinzufügen oder entfernen von Variationen.
    OK - mach ich mal so. Aber klappt das denn? Darf ein KEY im Dictionary nicht nur einmalig sein? Bei mir wäre ein STRING mehrfach gleich, die anderen unterscheiden sich in der Kombination aber wiederholen sich trotzdem.

    VB.NET-Quellcode

    1. DIM meineVariable as Dictionary (Of String, String)
    2. meineVariable.Add("Objekt1" , "Wert1")
    3. meineVariable.Add("Objekt1" , "Wert2")
    4. meineVariable.Add("Objekt1" , "Wert3")
    5. meineVariable.Add("Objekt2" , "Wert1")
    6. meineVariable.Add("Objekt2" , "Wert2")
    7. meineVariable.Add("Objekt2" , "Wert3")


    Geht das? Ich dachte immer dass bei DICTIONARY<TKEY,TVALUE> der KEY nicht mehrfach vorhanden sein darf. 8o ?(

    MSDN sagt:
    ​Jeder Schlüssel in einer Dictionary<TKey,TValue> muss gemäß dem Gleichheits Vergleich des Wörterbuchs eindeutig sein.

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

    @HenryV - also ich hab das mal ausprobiert mit dem Dictionary (Of String, List (Of String)) - das funktioniert soweit super, danke.
    So kann ich auch den Rückweg für mich machen - denn alles was ich ausgelesen habe muss ich später auch wieder schreiben in eine andere Variable. Ist zwar alles ein wenig mit Hin und Her verbunden aber ich glaube wenn man den Überblick über die Dimensionen nicht verliert geht das. Werde somit das ganze wohl noch Erweitern auf ein Dictionary (Of String, Dictionary (Of String, Boolean)) und dann klappt das glaub ich für mich wunderbar (muss nach der Prüfung für später noch mit einem Wahrheitswert hinterlegen ob die Werte abgerufen wurden oder nicht, deswegen noch das Boolean). Das spart mir somit sogar nochmal 35 Variablen die nämlich die späteren Prüfwerte nochmal beinhaltet hätten. Somit danke.

    Hier noch meine Zusammenschusterung (NEIN die Variablennamen hier sind nicht die realen Variablennamen):

    VB.NET-Quellcode

    1. Dim zaehlerProgramme as Integer
    2. Dim Sammelsorium As New Dictionary(Of String, List(Of String))
    3. Sammelsorium.Add("ObjektSammlung1", ObjektSammlung1)
    4. Sammelsorium.Add("ObjektSammlung2", ObjektSammlung2)
    5. ...
    6. Sammelsorium.Add("ObjektSammlung35", ObjektSammlung35)
    7. Dim Suchwert As New List(Of String)
    8. Suchwert = Sammelsorium(RegistryWertAbfrage)
    9. For zaehlerUmfang As Integer = 0 To Suchwert.Count - 1
    10. If Not ObjektSammlungNichtInstalliert Is Nothing AndAlso ObjektSammlungNichtInstalliert.Contains(Suchwert(zaehlerUmfang)) Then
    11. ObjektSammlung1auswertung.Add(Suchwert(zaehlerUmfang), False)
    12. Else
    13. ObjektSammlung1auswertung.Add(Suchwert(zaehlerUmfang), True)
    14. zaehlerProgramme += 1
    15. End If
    16. Next
    17. If zaehlerProgramme = Suchwert.Count Then
    18. Hauptformular.RadioButton_InstallVoll.Checked = True
    19. Else
    20. Hauptformular.RadioButton_InstallTeil.Checked = True
    21. End If
    22. 'ObjektSammlung1auswertung ...bis... ObjektSammlung35auswertung wird noch in das Dictionary aufgenommen und wird dann der Teil mit dem BOOLEAN Wert
    23. 'zaehlerProgramme ist ein interner Zähler um eine Menge an Werten zu Überprüfen


    Aber zur Grundfrage nochmal (VariablenINHALT als VariablenNAMEN nutzen) - hat da jemand eine Lösung, also ohne es nochmal zu Verschachteln?

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

    ThomasG82 schrieb:

    Aber zur Grundfrage nochmal (VariablenINHALT als VariablenNAMEN nutzen) - hat da jemand eine Lösung, also ohne es nochmal zu Verschachteln?

    könnte mir vorstellen das sowas mit CodeDom möglich ist. Gearbeitet hab ich damit jedoch noch nie...

    Allerdings ist das was du da machen willst eher ein Logik Problem. Du solltest deine Problemstellung soweit abstrahieren, dass es am Ende egal ist wie die Keys tatsächlich heißen.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    mrMo schrieb:

    CodeDom
    ist für dieses Problem völlig oversized.
    Ein Dictionary ordentlich eingesetzt sollte die Lösung sein.
    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!
    @mrMo - hab mir das mit dem CodeDom mal bei Microsoft Docs angeschaut - ich glaub da hat @RodFromGermany recht, das ist für mich als Umfang völlig "übermächtig".
    Ich hab jetzt wirklich alles über ein verschachteltes Dictionary realisiert. Das war zwar ein wenig tricky aber hat funktioniert.
    Somit hab ich ein Dictionary (Of String, Dictionary (Of String, Boolean)) und lese alle Werte, die ich benötige, aus jeweils zwei getrennten externen Dateien ein. Im der ersten Datei stehen meine Objekte (35 Varianten) und die weiteren Dateien enthalten für die jeweiligen Objekte die Werte (bis zu 7 Werte). Die Dateien haben dann den Objektnamen und somit kann ich alles auch sehr simple erweitern oder verringern.
    1. externe Datei einlesen (liegt in My.Resource) - alle Objektvarianten in ein Array einlesen.
    2. Array in einer Schleife durchlaufen und die entsprechende Datei laut Objektvariante einlesen.
    3. Die Werte in das erste Dictionary (Of String, Boolean) einlesen.
    4. Die Werte des Array (Objektvarianten) mit den jeweiligen Werten des Dictionary zusammensetzen.

    Wenn es interessiert wie es läuft - hier ein Spoiler
    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'Einlesen der Objektwerte nach Objektvarianten (bis zu 35)
    2. For iOV As Integer = 0 To ObjektVarianten.Count - 1
    3. 'Einlesen der Txt-Datei mit dem Werten der aktuellen ObjektVarianten
    4. Dim ZeilenOjektWerte As String() = My.Resources.ResourceManager.GetString(ObjektVarianten.Keys.ElementAt(iOV)).Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
    5. 'Erstellen eines vorübergehenden Dictionary um die Werte einlesen und aufteilen zu können
    6. Dim ZeilenWerte As New Dictionary(Of String, Boolean)
    7. 'Übergabe der Werte - standardmäßig alle als FALSE gekennzeichnet
    8. For iZOW As Integer = 0 To ZeilenOjektWerte.Count - 1
    9. ZeilenWerte.Add(ZeilenOjektWerte (iZOW), False)
    10. Next
    11. 'Übergabe des Dictionary's mit Werten zur Zuordnung zu der jeweiligen ObjektVariante
    12. 'Endversion: ObjektVarianteName(1-n), WertName(1-n), TRUE/FALSE je Wert
    13. ObjektVariantenWerte.Add(ObjektVarianten.Keys.ElementAt(iOV).ToString, ZeilenWerte)
    14. Next


    Somit muss ich nur einmal einen definitiven Dateinamen wissen - den Dateinamen, der die Objektvarianten enthält. Alles weitere läuft komplett dynamisch. Grundproblem also damit gelöst, Code um mehr verkürzt als eigentlich geplant, Programmierer (ich) zufrieden und ein bisschen was gelernt.
    Wo ich etwas basteln musste war der Punkt an dem ich dem ResourceManager erklären musste welche Datei er nutzen soll ohne, dass ich es in dem Moment selber wusste - sprich - wie kann ich den Inhalt der Variable als Namen einer Variable/Datei nutzen. Also mein Problem bloß an anderer Stelle.
    Aber siehe da - My.Resources.ResourceManager.GetString brachte mich ans Ziel - also GetString war hier das Lösungswort.
    @a.b_om - ja für mich ist es erledigt - danke.
    Die Schleife an sich ging ja auch (also in Verbindung mit Wenn-Dann-Abfragen) aber siehe Post #3 ff. - ich wollte ja Dynamic und die bekomme ich mit festen Fragen und Schleifen nicht weil ich alles vorgeben muss (also ich muss wissen wonach ich Frage). Das ganze hatte ich ja dank eurer Hilfe und explizit mit der Idee von @HenryV und @RodFromGermany im Post #13 verbessert. Jetzt hab ich halt nochmal ein bisschen an der Logikschraube in meinem Kopf gedreht und insgesamt ist das Ergebnis Post #17 - herausgekommen.
    Jetzt ist es dynamisch, arbeitet von selbst alles ab und liefert mir das Ergebnis in auswertbarer und weiterverarbeitender Logik.

    Somit nochmals danke an alle

    ? Was meinst du mit - du verstehst die letzten 3 Linien im Post nicht ?

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