Durch ein Enum iterieren

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

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Durch ein Enum iterieren

    Hallo,

    Ich habe mir in einer separaten Klasse eine Methode und einen Enum gebaut, und wollte diese Methode dann mittels des Enums durchiterieren, jedoch gibts da das Problem "der qualifizierende Ausdruck wird nicht ausgewertet"

    Beispiel:

    VB.NET-Quellcode

    1. Friend Class Artsys
    2. Friend Enum Art
    3. Schnell
    4. Mittel
    5. Langsam
    6. End Enum
    7. Friend Sub SetArt(a as Art)
    8. 'Select Case auf a
    9. End Sub
    10. End Class
    11. Friend Class Form1
    12. ...
    13. For Each a In {Artsys.Art.Schnell, Artsys.Art.Mittel, Artsys.Art.Langsam}
    14. SetArt(a)
    15. Next
    16. ...
    17. End Class


    Ist das noch zu retten? Und was ist hier das Problem?

    Viele Grüße
    Der Pseudocode funktioniert aber nicht, da SetArt außerhalb von Artsys nicht erreichbar ist. Aber wenn ich Artsys instanziiere und SetArt aufrufe, kommt kein entsprechender Fehler oder eine derartige Randbemerkung.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Foo As New Artsys
    4. For Each a In {Artsys.Art.Schnell, Artsys.Art.Mittel, Artsys.Art.Langsam}
    5. Foo.SetArt(a)
    6. Next
    7. End Sub
    8. End Class
    9. Friend Class Artsys
    10. Friend Enum Art
    11. Schnell
    12. Mittel
    13. Langsam
    14. End Enum
    15. Friend Sub SetArt(a As Art)
    16. Select Case a
    17. Case Art.Langsam
    18. End Select
    19. End Sub
    20. End Class

    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.
    Wenn du Art erweiterst, müsstest du auch die Liste in der ForEach Schleife jedes Mal anpassen.

    Einfacher geht es mit ...

    VB.NET-Quellcode

    1. For Each EnumValue In System.Enum.GetValues(GetType(Art)).Cast(Of Art)
    2. Next


    Oder wenn du in Artsys eine Shared Property einfügst ...

    VB.NET-Quellcode

    1. Friend NotInheritable Class Artsys
    2. Public Enum Art
    3. Schnell
    4. Mittel
    5. Langsam
    6. End Enum
    7. Public Shared ReadOnly Property Items As IEnumerable(Of Art)
    8. Get
    9. Return System.Enum.GetValues(GetType(Art)).Cast(Of Art)
    10. End Get
    11. End Property
    12. End Class
    13. ...
    14. Public Sub MachWasMitArt()
    15. For Each Item In Artsys.Items
    16. Next
    17. End Sub
    Warum so kompliziert?

    VB.NET-Quellcode

    1. Friend Enum Art
    2. Schnell
    3. Mittel
    4. Langsam
    5. End Enum
    6. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    7. For Each a As Art In System.Enum.GetValues(GetType(Art))
    8. Console.WriteLine(a.ToString())
    9. Next
    10. End Sub
    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!
    Ups, habe das Beispiel erst ohne zweite Klasse gemacht, dann habe ich aber gedacht, das könnte vielleicht auch zu dem Fehler führen, deswegen hat die Methode SetArt keine Instanz.

    Also eigentlich mit Instanz, ich hoffe die Lösung bleibt gleich. Es scheint zumindest zu funktionieren

    VB.NET-Quellcode

    1. Friend Class Artsys
    2. Friend Enum Art
    3. Schnell
    4. Mittel
    5. Langsam
    6. End Enum
    7. Friend Sub SetArt(a as Art)
    8. 'Select Case auf a
    9. End Sub
    10. End Class
    11. Friend Class Form1
    12. ...
    13. Dim ArtSysInstanz as New Artsys()
    14. For Each a as ArtSys.Art In System.Enum.GetValues(GetType(ArtSys.Art))
    15. ArtSysInstanz.SetArt(a)
    16. Next
    17. ...
    18. End Class

    Haudruferzappeltnoch schrieb:

    ich hoffe die Lösung bleibt gleich
    So isses.
    Du brauchst den Typ, nicht aber die Instanz.
    Damit Du den Typ siehst, muss er als Public oder Friend deklariert sein.
    Übrigens genügt es, die Klasse mit Friend zu deklarieren, Sub-Typen werden dann darauf "begrenzt", wenn sie "öffentlicher" sind.
    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!
    Da die Artsys-Klasse aber so noch keinen Sinn ergibt, da sie effektiv gar nichts kann, frag ich mich, wie sinnvoll das eingeschachtelte Enum hier jetzt ist. Denn was soll da jetzt bitte in SetArt passieren? Es gibt in der Klasse ja nur das Enum und die Methode. Oder werden da jetzt Systemfunktionen aufgerufen? Wofür stehen eigentlich Artsys und Art? Klar, der jetzige Code funktioniert. Aber ob er so Sinn ergibt, können wir ohne Kontext nicht bewerten.
    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.
    Der Kontext ist folgender:
    Ich führe in meiner Datenstruktur mehrere Linq-Abrufe durch, diese greifen in der DataTable nur auf unterschiedliche Datensätze zu.

    VB.NET-Quellcode

    1. query1 = From t In table Where t.Column >= 'Bedingung nach Art1
    2. query2 = From t In table Where t.Column >= 'Bedingung nach Art2
    3. ...


    Zu jeder query muss nur ein Wert weggeschrieben werden.
    Das Ganze ist unübersichtlich und ich hab es jetzt in eine Schleife gepackt, in der die Bedingung quasi durchiteriert wird. Sieht auf jeden Fall sauberer aus.

    SetArt läuft in der Schleife mit und erzeugt mir in den Klassenvariablen der Instanz die Bedingungen, jeweils davon abhängig welche man denn gerade braucht.
    Das Enum habe ich genommen weil ich finde, dass man so sehr verständlich verschiedene Fälle in Methoden unterscheiden kann.

    Artsys, ja ein besserer Name ist mir nicht eingefallen für das Ding das Arten unterscheidet
    probierma

    VB.NET-Quellcode

    1. Friend Class Artsys
    2. Friend Enum Art
    3. Schnell
    4. Mittel
    5. Langsam
    6. End Enum
    7. Friend Shared Sub SetArt(a As Art)
    8. 'Select Case auf a
    9. End Sub
    10. End Class
    11. Friend Class Form1
    12. For Each a As Artsys.Art In System.Enum.GetValues(GetType(Artsys.Art))
    13. Artsys.SetArt(a)
    14. Next
    15. ...
    16. End Class
    dann brauchst du keine Artsys-Instanz.
    Eine Instanz braucht man nur, wenn sie sich einen bestimmten Status merken soll.
    Dein ArtSys soll aber nur verschiedene Enums auseinanderhalten können.
    Nichts, was eine simple shared Methode nicht auch könnte - zumindest nach dem, was du bisher davon gezeigt hast.

    Haudruferzappeltnoch schrieb:

    aber das könnte man auch alles Shared setzen
    sofern in der Prozedur nicht auf Klassenmember verwiesen wird. Wenn in einer Klasse nur Shared Prozeduren und Member vorkommen, kannst Du aus dieser Klasse ein Modul machen.
    docs.microsoft.com/de-de/dotne…atements/module-statement
    Klasse oder Modul
    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!

    Haudruferzappeltnoch schrieb:

    Welchen Vorteil hat es auf Instanzen zu verzichten?
    So was:

    VB.NET-Quellcode

    1. Using dlg = New MessageBox()
    2. dlg.Message = "Message"
    3. dlg.ShowDialog()
    4. End Using
    vs

    Visual Basic-Quellcode

    1. MessageBox.Show("Message")

    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!
    Wenn Du mit verschiedenen ArtSys-Zustände gleichzeitig und unabhängig voneinander arbeiten willst/musst, dann brauchst Du Instanzen. Sonst nicht.
    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.

    Haudruferzappeltnoch schrieb:

    rumgehackt
    Ich hab da einfach das erste genommen, was mir vom Forum angeboten wurde.
    Ich bin in C# unterwegs, da gibt es statische Klassen, das (na ja) Äquivalent für Module.
    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:

    Ich hab da einfach das erste genommen, was mir vom Forum angeboten wurde.
    Meinst du also, du hättest da einfach einen ziemlich beliebigen Thread verlinkt statt eines bestimmten Posts, von dem du weisst, dass er eine zielführende Antwort auf die Frage enthält?
    Hmm - so ein "Link hinschmeissen" wäre ja anti-hilfreich, weil verwirrt mehr, als dasses klärt.
    Und da muss man sich am Ende auch nicht mehr wundern/ärgern über User, die die Links einfach ignorieren, die man ihnen gibt.



    Hmm - ich glaub das sollte man nicht unbewertet stehen lassen:
    Wenn in einer Klasse nur Shared Prozeduren und Member vorkommen, kannst Du aus dieser Klasse ein Modul machen.
    Module haben leider doch einen Unterschied zu c# - static class: Alle ihre Friend/Public Member sind überall sichtbar.
    Also einen Shared Class-Member musst du über den Klassen-Namen addressieren - bei Modul kannste den Modul-Namen weglassen.
    Das gilt auch für Intellisense, also ein Modul mit 50 Membern müllt die Intellisense gehörig zu.
    Und bei mehreren Modulen zu verschiedenen Themen vermischen die sich auch munter.
    Das wäre ein guter Grund, auch mal Klassen zu verwenden, mit nur Shared Membern drinne.

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

    Ich benutze nur für einen Zweck Module: Extensions. Eben weil die anders nicht implementiert werden können.
    Für alles andere jener Art: NotInheritable Klassen mit Shared-Methoden.
    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.
    @ErfinderDesRades Das "Rumhacken" auf den Moduln impliziert doch die Aussage, sie dann lieber doch nicht zu verwenden.
    Die völlige Sichtbarkeit der Friend/Public Member ohne Modulnamen ist leider so ein gewachsenes Ding, das kenne ich noch von VB3.
    Da hätte Microsoft eigentlich mit der Einführung der Klassen einen Riegel vorschieben müssen.
    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!