Booleans, wie am besten Abfragen?

  • VB.NET

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

    Booleans, wie am besten Abfragen?

    Hallo,

    hab hier eine Funktion die prüfen soll, ob gewisse Eigenschaften zutreffen.

    VB.NET-Quellcode

    1. Private Function CheckForTextBoxContent() As Boolean
    2. Dim IsOk As New List(Of Boolean)
    3. IsOk.Add({OnOffVisCreateMessage.CheckedState AndAlso Not OnOffVisCreateMessageRandomly.CheckedState, VisMessageConstantText.TextLength = 0}.All(Function(c) c = True))
    4. IsOk.Add({OnOffVisCreateGbEntry.CheckedState AndAlso Not OnOffVisCreateGbEntryRandomly.CheckedState, VisGbEntryConstantText.TextLength = 0}.All(Function(d) d = True))
    5. IsOk.Add({OnOffVisCreatePicComment.CheckedState AndAlso Not OnOffVisCreatePicCommentRandomly.CheckedState, VisPicCommentConstantText.TextLength = 0}.All(Function(e) e = True))
    6. Return IsOk.All(Function(f) f = True)
    7. End Function


    Die Funktion klappt so nicht.. Und ist meiner Meinung nach auch nicht gerade das Idealste.


    Was ich prüfen möchte:

    Allgemein soll die Prüfung erst stattfinden, wenn OnOffVisCreateXXXX.CheckedState true ergibt.

    Ist OnOffVisCreateXXXXRandomly.CheckedState true -> Nichts prüfen
    Ist OnOffVisCreateXXXXRandomly.CheckedState false -> Prüfen ob VisXXXXConstantText.TextLength = 0 ist

    Wenn eine Prüfung nicht zutrifft sollte als Return ein False herauskommen.
    Wie kann man das so kurz wie möglich hinbekommen?

    Andauernd Andalso Andalso finde ich irgendwie eher nicht so gut. Gibts da noch Alternativen?

    VB.NET-Quellcode

    1. Return _
    2. ((OnOffVisCreateMessage.CheckedState AndAlso Not OnOffVisCreateMessageRandomly.CheckedState) AndAlso VisMessageConstantText.TextLength = 0) AndAlso _
    3. ((OnOffVisCreateGbEntry.CheckedState AndAlso Not OnOffVisCreateGbEntryRandomly.CheckedState) AndAlso VisGbEntryConstantText.TextLength = 0) AndAlso _
    4. ((OnOffVisCreatePicComment.CheckedState AndAlso Not OnOffVisCreatePicCommentRandomly.CheckedState) AndAlso VisPicCommentConstantText.TextLength = 0)

    Ist das kürzeste und einfachste was mir einfällt.

    AndAlso ist hierbei der entscheidende Befehl: sobald ein Teil false ergibt, wird sofort abgebrochen und false zurückgegeben. Wenn sowieso alles true sein muss, kannst und musst du AndAlso bzw. AndAlso Not nutzen. Daher: was spricht gegen AndAlso Not.

    Hier Linq zu nutzen ist zu overpowered und Performance fressend. Guck dir den Code mal im IL an und freue dich über den Overhead, den dir der Compiler erzeugt. Nutz lieber eine große Abfrage. a) schneller und b) nicht ganz so viel clusterfuck. (hier kann schon fast von Linq-Missbrauch (oder Vergewaltigung) reden. Ja .. persönliche Meinung)
    So wird aber auch immer ins Return das OnOffVisCreateXXXX.Checkedstate einbezogen,
    auch wenn es false ist.

    Sollte diese Bedigung nicht erfüllt sein, soll gar nicht weiter geprüft werden...

    Andalso bricht es ja ab, nun ist es aber so, dass das Return dann demnach ja auch false wird.

    Hab ich z.B die erste Zeile der Bedingung von deinem Code true
    und OnOffVisCreateGbEntry.CheckedState ist false, so wird das dennoch einbezogen und das ganze Return wird false -> Das soll ja eben nicht.
    Was soll es dann machen? Dein Code prüft immer auf All => dasselbe wie AndAlso.
    Wenn du prüfen willst, ob irgendeiner dieser drei Blocks true ist, dann ergibt sich nur eine Änderung:

    VB.NET-Quellcode

    1. Return _
    2. ((OnOffVisCreateMessage.CheckedState AndAlso Not OnOffVisCreateMessageRandomly.CheckedState) AndAlso VisMessageConstantText.TextLength = 0) OrElse _
    3. ((OnOffVisCreateGbEntry.CheckedState AndAlso Not OnOffVisCreateGbEntryRandomly.CheckedState) AndAlso VisGbEntryConstantText.TextLength = 0) OrElse _
    4. ((OnOffVisCreatePicComment.CheckedState AndAlso Not OnOffVisCreatePicCommentRandomly.CheckedState) AndAlso VisPicCommentConstantText.TextLength = 0)

    OrElse: sobald true, abbrechen und true zurückgeben. Wäre äquivalent zu Any().
    @AliveDevil
    Dein System funktioniert soweit ganz gut, jedoch will der TE, so wie ich es verstanden habe, die Textlänge nur prüfen, wenn die zweite Checkvox nicht aktiviert ist.

    @Kevin Hombre
    Ich würde das System

    VB.NET-Quellcode

    1. (OnOffVisCreateXXXXX.CheckedState AndAlso (OnOffVisCreateXXXXXRandomly.CheckedState OrElse VisXXXXConstantText.TextLength = 0))

    benutzen, falls es überhaupt funktioniert :D, was ich jedoch denke (einfach mal ausprobieren ;)). Erklärung:
    Wenn die erste Checkbox aktiviert ist, geht es zur nächsten Prüfung über.
    Zweite Prüfung:
    Wenn die zweite Checkbox nicht aktiviert ist, guckt es, ob die Textlänge gleich Null ist.

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

    VB.NET-Quellcode

    1. Return _
    2. ((OnOffVisCreateMessage.CheckedState AndAlso Not OnOffVisCreateMessageRandomly.CheckedState) AndAlso VisMessageConstantText.TextLength = 0) OrElse _
    3. ((OnOffVisCreateGbEntry.CheckedState AndAlso Not OnOffVisCreateGbEntryRandomly.CheckedState) AndAlso VisGbEntryConstantText.TextLength = 0) OrElse _
    4. ((OnOffVisCreatePicComment.CheckedState AndAlso Not OnOffVisCreatePicCommentRandomly.CheckedState) AndAlso VisPicCommentConstantText.TextLength = 0)



    Das gibt auch False zurück wenn OnOffVisCreateMessage oder ein anderes von den CreateDingern nicht gecheckt ist..
    @Gonger96
    Ich was der mit'm Gedächtnisblackout :S vb-paradise ohne Avatare etc. ist so verwirrend (ich schiebs halt mal aufs türkische Internet :D) X(. Aber danke für den Hinweis :).

    @Artentus
    Dass du If brauchst, stimmt in diesem fall nicht:
    Das erste wenn, dann ist ja (stark vereinfacht, mit 'b_X' als zu prüfende Booleans):
    Wenn b_1 = True, dann soll es weiterprüfen, ansonsten nicht: Genau das macht AndAlso
    Wenn b_2 = True, dann soll true kommen, ansonsten soll b_3 geprüft werden: Das macht wiederum OrElse
    Ergebnis:
    b_1 AndAlso (b_2 OrElse b_3)
    Also, wofür brauchste hier If :P?

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

    @Kevin Hombre
    Erstmal eine ganz dumme Frage: programmierst du unter Option Strict Off? Weil .CheckedState kenne ich als Enum - das ist ein Integer und kein Boolean! Also Option Strict auf ON schalten!

    Ansonsten: Wirst du für kurzen, nicht debug- und lesbaren Code bezahlt? Schreibe doch mal mehrere Zeilen. Wenn ich so einen 'Einzeiler-Block' schreibe guck ich hinterher auch ganz schön dumm aus der Wäsche wenn er nicht funktioniert^^ Gestalte deinen Code doch leserlich. Also ein paar Hilfsvariablen und zusätzliche Zeilen verwenden. Dann könntest du auch Haltepunkte setzten.

    Und btw: Du willst sicher mittendrin unterbrechen und false zurückgeben, damit es "schneller" ist. Sowas halte ich für Blödsinn. Was der Compiler hinterher aus der Funktion macht ist eine Geschichte für sich. Der Weg über die List(of Boolean) erzeugt aber gewisse mehr Overhead als alles andere^^ Also so schreiben, dass man es gut verstehen und debuggen kann. Optimieren erst wenn es überhaupt läuft.

    Kevin Hombre schrieb:

    Wie kann man das so kurz wie möglich hinbekommen?
    Ziel sollte hier nicht die Kürze des Quelltextes, sondern die Verständlichkeit, die Debug-barkeit und die Wartbarkeit sein.
    Da ist es immer besser, ein paar Zeilen mehr hinzuschreiben und ggf. Zwischenvariablen zu verwenden.
    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!
    es scheint sich immer um eine Kombination zu handeln aus zwei Checkbox-ähnlichen Dingsbumsen und einer Textbox. Das kann man schön in einen anonymen Typen zusammenfassen. Im weiteren kannman dann fürs einzelne anonyme Objekt ein in .All verwendbares Prädikat proggen.

    VB.NET-Quellcode

    1. Private Function CheckForTextBoxContent() As Boolean
    2. Dim toCheck = {New With {.Create = OnOffVisCreateMessage, .Random = OnOffVisCreateMessageRandomly, .txt = VisMessageConstantText}, _
    3. New With {.Create = OnOffVisCreateGbEntry, .Random = OnOffVisCreateGbEntryRandomly, .txt = VisGbEntryConstantText}, _
    4. New With {.Create = OnOffVisCreatePicComment, .Random = OnOffVisCreatePicCommentRandomly, .txt = VisPicCommentConstantText}}
    5. Return toCheck.All(Function(item) item.Create.Checked AndAlso Not item.Random.Checked AndAlso item.txt.TextLength = 0)
    6. End Function
    in #5 inne anonyme Methode kannste deine Anforderungs-Logik umsetzen - die habichnicht wirklich verstanden gehabt
    Hey,

    hab das mal getestet, doch leider funktioniert es nicht.


    VB.NET-Quellcode

    1. Dim isok As Boolean = True
    2. If OnOffVisCreateMessage.CheckedState Then
    3. If Not OnOffVisCreateMessageRandomly.CheckedState AndAlso VisMessageConstantText.TextLength = 0 Then
    4. isok = False
    5. End If
    6. End If
    7. If OnOffVisCreateGbEntry.CheckedState Then
    8. If Not OnOffVisCreateGbEntryRandomly.CheckedState AndAlso VisGbEntryConstantText.TextLength = 0 Then
    9. isok = False
    10. End If
    11. End If
    12. If OnOffVisCreatePicComment.CheckedState Then
    13. If Not OnOffVisCreatePicCommentRandomly.CheckedState AndAlso VisPicCommentConstantText.TextLength = 0 Then
    14. isok = False
    15. End If
    16. End If


    So würde es funktionieren. Gefällt mir zwar nicht gut aber wenn man es anders nicht machen kann.

    Vllt. gibts da ja doch noch ne Lösung für?
    Du kannst alle If-Abfragen auch mit Operatoren kombinieren:

    VB.NET-Quellcode

    1. Return Not ((OnOffVisCreateMessage.CheckedState AndAlso Not OnOffVisCreateMessageRandomly.CheckedState AndAlso VisMessageConstantText.TextLength = 0) OrElse _
    2. (OnOffVisCreateGbEntry.CheckedState AndAlso Not OnOffVisCreateGbEntryRandomly.CheckedState AndAlso VisGbEntryConstantText.TextLength = 0) OrElse _
    3. (OnOffVisCreatePicComment.CheckedState AndAlso Not OnOffVisCreatePicCommentRandomly.CheckedState AndAlso VisPicCommentConstantText.TextLength = 0)) Then

    RodFromGermany schrieb:

    Ziel sollte hier nicht die Kürze des Quelltextes, sondern die Verständlichkeit, die Debug-barkeit und die Wartbarkeit sein.
    Da ist es immer besser, ein paar Zeilen mehr hinzuschreiben und ggf. Zwischenvariablen zu verwenden.
    @Kevin Hombre: Das haste noch nicht verstanden.
    Was ist, wenn Du in einem halben Jahr diesen Code wieder ansiehst und anpassen willst?
    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!