Was ist das besondere an Enums?

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

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

    Was ist das besondere an Enums?

    Hallo,

    ich muss hier mal nachfragen, wann nutzt ihr Enums? Was haben die für einen Mehrwert?

    Hier kann ich die Variable Buchstabe.A als Nummerierung verwenden:

    VB.NET-Quellcode

    1. Enum Buchstabe
    2. A
    3. B
    4. C
    5. D
    6. E
    7. End Enum


    Aber irgendwie ist es doch dasselbe wenn ich es mit klassischen Variablen mache, nur ist die Schreibweise etwas aufwändiger:

    VB.NET-Quellcode

    1. Dim A = 1
    2. Dim B = 2
    3. Dim C = 3
    4. Dim D = 4
    5. Dim E = 5


    Gibt es da noch wichtige Unterschiede?

    Viele Grüße
    @Haudruferzappeltnoch Enums fangen bei 0 an. ;)
    Ich nutze Enums bei Sachen, die aufzuzählen sind, z.B. die Dateiformate beim Speichern von Bildern {Png, Jpeg, Bmp8, Bmp16, ...}.
    Das Besondere daran: Sie sind ein eigener Datentyp, so können Enums typsicher an Prozeduren übergeben werden.
    Wenn Du A und woanders AA als numerische Werte übergibst, kann der Compiler nicht wissen, dass AA eigentlich logisch was anderes ist als A, auch wenn sie den selben numerischen Wert haben.
    Elegant ist es, mit einem Wert MyEnum.Last im Code zu testen, ob neue Enum-Werte hinzugekommen sind, da schreiben sich Erweiterungen und Anpassungen wesentlich einfacher, wenn da ein Debugger.Break() steht und Du sofort an der richtigen Stelle den neuen Code einfügen kannst.
    In diesem Kontext ist Throw New NotImplementedException("Neuer Wert") eher destruktiv.
    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!
    Den Mehrwert sieht man halt erst wenn man weiß/sieht wie es verwendet wird.
    Hier ein überarbeiteter, stark verkürzter und zusammengeschnippselter C#-Code

    Spoiler anzeigen

    C#-Quellcode

    1. public enum ContactTypeEnum : ushort
    2. {
    3. Private = 0,
    4. Business = 1
    5. }
    6. public enum SalutationEnum : ushort
    7. {
    8. Herr = 1,
    9. Frau = 2,
    10. Firma = 4,
    11. Institution = 5
    12. }
    13. public class BusinesspartnerData
    14. {
    15. public int ID { get; set; }
    16. public ContactTypeEnum ContactType { get; set; }
    17. public SalutationEnum Salutation { get; set; }
    18. public string Accountnumber { get; set; }
    19. public string Lastname { get; set; }
    20. public string Firstname { get; set; }
    21. public string Supplementname { get; set; }
    22. public string ISOCountryCode { get; set; }
    23. public string Street { get; set; }
    24. public string City { get; set; }
    25. public string Postalcode { get; set; }
    26. }
    27. private void ImoprtBusinesspartner()
    28. {
    29. SalutationEnum salutation = SalutationEnum.Herr;
    30. ContactTypeEnum contactType = ContactTypeEnum.Private;
    31. Businesspartner = new List<BusinesspartnerData>();
    32. string konto;
    33. string nachname;
    34. string vorname;
    35. //weitere Deklarationen
    36. //Daten einlesen und zuweisen
    37. //neuen Datensatz anlegen
    38. Businesspartner.Add(new BusinesspartnerData
    39. {
    40. ID = zaehler,
    41. ContactType = contactType,
    42. Salutation = salutation,
    43. Accountnumber = konto,
    44. LastName = nachname,
    45. FirstName = vorname,
    46. Supplementname = mittelname,
    47. ISOCountryCode = land,
    48. Street = strasse,
    49. City = ort,
    50. Postalcode = plz
    51. });
    52. }


    Es ließ sich leider nicht eben mal so in VB.Net umwandeln und habe daran auch keine weitere Zeit verschwendet.
    Die Enums heißen bei mir nicht "Enum" hinten drann, dient nur der besseren Visualisierung hier.
    Ich hoffe es haben sich keine Fehler eingeschlichen.
    lade dir das Buch "Visualbasic 2005" von Löffelmann herunter.
    Das Kapitel zu Enums hat mir ganz besonders gut gefallen.
    Weil - wie das so ist - ich dachte, ich wüsste alles... ... hihi!

    In Kürze: Ein Enum ist ein Datentyp. Deine Variablen sind Variablen. Das ist schomal eine ganz grundlegende Verwechslung.

    Also ein Datentyp - so etwas wie Boolean.
    Von Boolean kann es nur zwei Stück geben: True und False.

    Von einem Enum kann es genau so viele geben, wie definiert sind. (Und nicht mehr)
    Also der DockStyles gibt es sechse, Checkstate gibts drei und von deinen Buchstaben gibts fünf.
    Mehr gibts nicht, und das ist der Sinn der Sache.
    Da es nicht mehr gibt von einem Enum, als vorgesehen sind, kannst du einer so deklarierten Variablen keinen Unsinn zuweisen.

    Deine Integer-Variablen A - E kannste ja jeder anderen Integer-Variablen zuweisen, (und 2^32-5 weitere Werte ausserdem).
    Du kannst ja sogar aus deinem A ein E machen - wäre syntaktisch korrekt: A = E



    Edit: Aber gut, dass du fragst :thumbsup:
    Ohne Enums zu verstehen (und zwar richtig) kann man nix werden in .Net.
    Viele andere Dingen, an denen man IMO ausserdem nicht vorbei kommt, sind hier aufgeschrieben: Datenverarbeitungs-Vorraussetzungen
    Und wie gesagt: Lad dir das Buch.

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

    Enums sind für mich sprechende Variablenwerte.
    Wenn ich If AccountType = 2 Then habe, ist das für mich viel schwieriger zu interpretieren als If AccountType = AccountTypes.Cash Then
    Außerdem kann man Enums durch geschickte Verwendung von DataBinding, Attributen und Reflection noch besser nutzen. Dann kann man z.B. englische Begriffe im Code verwenden, während man sich deutsche im GUI anzeigen lässt.
    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.
    Enums ersetzten „Magic Numbers“.

    „Ein im Quellcode eines Programms auftauchender Zahlenwert (auch englisch „hard coded value“ genannt), dessen Bedeutung sich nicht unmittelbar erkennen lässt – seine Bedeutung ist somit „magisch“. Derartige Magische Zahlen sind zu vermeiden und durch gut benannte Konstantendefinitionen zu ersetzen, deren Namen Bedeutung und Herkunft klar angeben.“
    Quelle: de.m.wikipedia.org/wiki/Magische_Zahl_(Informatik)
    "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
    Nee, A und E sind beide vom selben vom Datentyp Buchstabe, aber deren Werte werden explizit im Code durch den "Enum-Block" festgelegt. Damit sind die Werte fix und können nicht mehr geändert werden. Daher klappt die Zuweisung Buchstabe.A = Buchstabe.E nicht. Eine Mehrfachvergabe eines Werts ist aber erlaubt, also A und E können beide den Wert 0 zugewiesen bekommen; ist m.E. aber sinnfrei.
    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:

    ich muss hier mal nachfragen, wann nutzt ihr Enums? Was haben die für einen Mehrwert?

    Ich nutze viel Enum. Manchmal haue ich sogar mehrere Const, wenn die so in der MS-Doku zusammengehören und eigentlich keine Enum sind, in eine Enum. zb die Const IEIFLAG_OFFLINE, und weitere IEIFLAG_* Const. Schaut dann so aus.

    VB.NET-Quellcode

    1. Private Enum IEIFLAG_FLAGS As Integer
    2. IEIFLAG_OFFLINE = &H8&
    3. IEIFLAG_SCREEN = &H20&
    4. IEIFLAG_ORIGSIZE = &H40&
    5. IEIFLAG_QUALITY = &H200&
    6. IEIFLAG_REFRESH = &H400&
    7. End Enum

    Schon allein wegen der Intellisense. Eine Enum muss nicht zwangsweise mit 0 anfangen. Der erste Wert eines Member bestimmt den Wert der nachfolgenden Member wenn diesen explizit kein Wert zugewiesen wurde. B hätte hier dann 66, C dann 67 usw. Ab D gilt dann ein neuer Wert. F hätte dann die 102.

    VB.NET-Quellcode

    1. Private Enum Buchstaben As Integer
    2. A = 65
    3. B
    4. C
    5. D = 100
    6. E
    7. F
    8. End Enum

    Du findest auch in der MS-Doku diverse Enum wo mehrere Member, mit unterschiedlicher Bezeichnung, den gleichen Wert aufweisen können und ist gar nicht mal so ungewöhnlich. Ich nutze sowas ganz gern im Zusammenhang mit COM-Interfaces wenn ich deren Funktionen per VTableID aufrufe. Hier mal so ein Beispiel.

    VB.NET-Quellcode

    1. Private Enum vtb_Interfaces As Integer
    2. ' IUnknown
    3. QueryInterface = 0
    4. ' IPreviewHandler
    5. SetWindow = 3
    6. SetRect = 4
    7. DoPreview = 5
    8. Unload = 6
    9. SetFocus = 7
    10. QueryFocus = 8
    11. TranslateAccelerator_IPH = 9
    12. ' IInitializeWithFile / IInitializeWithStream / IInitializeWithItem
    13. Initialize = 3
    14. ' IPreviewHandlerVisuals
    15. SetBackgroundColor = 3
    16. SetFont = 4
    17. SetTextColor = 5
    18. ' IPreviewHandlerFrame
    19. GetWindowContext = 3
    20. TranslateAccelerator_IPHF = 4
    21. ' IThumbnailProvider
    22. GetThumbnail = 3
    23. ' IExtractImage
    24. GetLocation = 3
    25. Extract = 4
    26. ' IShellFolder
    27. ParseDisplayName = 3
    28. BindToObject = 5
    29. GetUIObjectOf = 10
    30. ' IShellItemImageFactory
    31. GetImage = 3
    32. End Enum
    Mfg -Franky-

    -Franky- schrieb:

    Eine Enum muss nicht zwangsweise mit 0 anfangen.
    Das wäre allerdings schlechter Code, denn eine nicht initialisierte Variable eines solchen Enums hätte den numerischen Wert 0.
    Ein StyleGuide fordert deswegen zur Vorgabe eines 0-Wertes auf.
    @Haudruferzappeltnoch Etwas ganz elegantes sind Flag-Enums, da werden die Werte als Zweierpotenzen vorgegeben und wie Bits einer Zahl behandelt:

    VB.NET-Quellcode

    1. Public Class Form1
    2. <Flags()>
    3. Public Enum Test
    4. None = 0
    5. a = 1
    6. b = 2
    7. c = 4
    8. d = 8
    9. e = 16
    10. f = 32
    11. End Enum
    12. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    13. Dim ff = Test.None
    14. ff = ff Or Test.b
    15. ff = ff Or Test.e
    16. If ff.HasFlag(Test.a) Then
    17. MessageBox.Show("has Test.a")
    18. End If
    19. If ff.HasFlag(Test.b) Then
    20. MessageBox.Show("has Test.b")
    21. End If
    22. If ff.HasFlag(Test.c) Then
    23. MessageBox.Show("has Test.c")
    24. End If
    25. End Sub
    26. End Class
    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:

    Das wäre allerdings schlechter Code, denn eine nicht initialisierte Variable eines solchen Enums hätte den numerischen Wert 0.
    Ein StyleGuide fordert deswegen zur Vorgabe eines 0-Wertes auf.

    Für den ersten, nicht initialisierten Member, gebe ich Dir recht. Der ist 0. Was aber machen wenn Du eine Enum aus der MS-Doku verwendest, wo eben nicht mit 0 angefangen wird und None = 0 eher zu einem Fehler führt weil es diesen Enum-Member zB. gar nicht für eine API/Interface usw. gibt und größer 0 sein muss? None = 0 impliziert in einer Enum, laut Intellisense, das ich diesen Member auch verwenden kann. Es gibt sicher solche Fälle wo 0 kein zulässiger Wert ist. Dann würde ich eher dazu neigen den Member DoNotUse = 0 zu verwenden. ;)
    Mfg -Franky-

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

    @-Franky- Klar.
    In diesem Falle würde ich diese Enums im Sinne einer Konstanten verwenden und keine Variablen dieses Typs erstellen.
    @Dksksm Dies funktioniert:

    VB.NET-Quellcode

    1. Public Enum Test
    2. 'None = 0
    3. a = 1
    4. b = 2
    5. End Enum
    6. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    7. ' Dies funktioniert:
    8. Dim ff = 0 'Test.None
    9. 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!
    @ ALL Wo sollte man den die Enums definieren. Was ich damit meine ist z.B.:

    Automarken
    Enum= VW,BMW, Audi,...

    Klassen im Projekt:
    Auto, Kunde, Rechnung, ...

    Ich würde die Enums in der Klasse Auto, Kunde nutzen wollen als Auswahl für Propertys, aber in welcher Klasse speichere ich die Enums. In einer extra Klasse z.B. Settings inkl. andere statischer readonly Propertys. Wie macht Ihr das mit Enums die in mehreren Klassen benutzt werden.
    codewars.com Rank: 4 kyu
    @nogood Automarken würden bei mir nach Auto oder einer Basisklasse davon kommen.
    Andere Enums in die hierarchisch niedrigste Klasse aller beteiligten Klassen oder eine spezielle Enum-Klasse.
    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:

    VB.NET-Quellcode

    1. Public Class Form1
    2. <Flags()>
    3. Public Enum Test
    4. None = 0
    5. a = 1
    6. b = 2
    7. c = 4
    8. d = 8
    9. e = 16
    10. f = 32
    11. End Enum
    Ich hingegen benutze nie den Wert 0 als Enum-Wert.
    Weil wenn man mit geflaggten Enums arbeitet, macht dieser Wert Probleme.
    ZB die Kombination Test.None OR Test.d funktioniert so nicht, weil ist mit Test.d identisch.

    ErfinderDesRades schrieb:

    ZB die Kombination Test.None OR Test.d funktioniert so nicht, weil ist mit Test.d identisch.

    C#-Quellcode

    1. Test.None OR Test.d == Test.d
    Was ist daran falsch?
    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!
    Hier kommt zwei Mal True raus.
    Ist tatsächlich iwie merkwürden.

    VB.NET-Quellcode

    1. Dim item = Test.None
    2. Dim matching = (Test.a Or Test.d).HasFlag(item)
    3. Label1.Text = matching.ToString()
    4. matching = (Test.None Or Test.d).HasFlag(item)
    5. Label2.Text = matching.ToString()
    Wenn ich Test.None rausnehme und durch CType(0, Test) ersetze, kommt ebenfalls True raus:

    VB.NET-Quellcode

    1. Dim item As Test = 0 'Test.None
    2. Dim matching = (Test.a Or Test.d).HasFlag(item)
    3. Label1.Text = matching.ToString
    4. matching = (item Or Test.d).HasFlag(item)
    5. Label2.Text = matching.ToString
    Da sollen sich andere den Kopf zerbrechen.
    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!
    Hi.

    Zwei Anwendungen finde ich Hilfreich.

    1. Beispiel: Gendern

    VB.NET-Quellcode

    1. Public Enum Gender
    2. Undefined = 0
    3. Neutral = 1
    4. Female = 2
    5. Diverse = 3
    6. Male = 4
    7. End Enum


    2. Beispiel: Arrays (und die Indexe)

    Angenommen es ist ein Array vorgegeben und ich kann mir nicht merken welcher Index was bedeutet,
    dann mache ich mir ein Enum, um Index zu Bezeichnen...

    Quellcode

    1. Public Enum Region
    2. North = 0,
    3. Central = 1,
    4. South = 2,
    5. 'etc...
    6. End Enum
    7. Public Enum Office
    8. Inbound = 0,
    9. Outbound = 1,
    10. Both = 2
    11. End Enum
    12. ' Achtung Code nicht Debuggt... ;)
    13. For Each region im Sales.Regions()
    14. For Each office in Sales.Regions(region).Offices()
    15. if Office(Enum.Central) Then
    16. Debug.WriteLine(someVariable += Offices(office).giveMeDaMoney())
    17. EndIf
    18. Next For
    19. Next For



    MfG und c.u. Joshi :)

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