none
Select Case funktioniert nicht wie gewünscht RRS feed

  • Frage

  • Hallo,
    ich will Winkelwerte mit einer Select Case - Anweisung auswerten.

        Dim angle As Double = 124.78

        Select Case angle
          Case 0, 90, 180, 270
            Return 1
          Case Is > 0 And CInt(angle < 90)       
            Console.WriteLine("Wert > 0 und < 90")               'in diese Case-Anweisung wird gesprungen, was bei einem Wert von 124.78 falsch ist
          Case Is > 90 And CInt(angle < 180)
            Console.WriteLine("eigentlich muss in diese Case-Anweisung gesprungen werden")        'hier ist eigentlich das Ziel
          Case Is > 180 And CInt(angle < 270)
            '
          Case Is > 270 And CInt(angle < 360)
            '
        End Select

    Kann mir jemand sagen, warum nicht "Case Is > 90 And CInt(angle < 180)" als richtiger Case-Zweig erkannt wird?
    Was muss ich ändern?


    Alexander

    Dienstag, 17. Mai 2011 21:54

Antworten

  • Hallo Alexander,

    Kann mir jemand sagen, warum nicht "Case Is > 90 And CInt(angle < 180)" als richtiger Case-Zweig erkannt wird?

    weils totaler Quatsch ist, was da steht? :)

    Ich weiß zwar nicht, was da wirklich bei rumkommen würde aber lies mal einfach ein wenig was zu "Is" und "And", wie Du sie hier verwendest.

      http://msdn.microsoft.com/de-de/library/kb136x1y.aspx

      http://msdn.microsoft.com/de-de/library/sdbcfyzh.aspx

    Das hat hier mit dem, was Du machen willst, nix zu tun.


    Eine Lösung könnte bspw. so aussehen:

    ---

    Select Case x
        Case 0, 90, 180, 270, 360
            ...
        Case 0 To 90
            ...
        Case 90 To 180
            ...
        Case 180 To 270
            ...
        Case 270 To 360
            ...
    End Select

    ---

    Man könnte zwar auch mit 90.00000000001 oder ähnlichem anfangen, da aber von oben nach unten gearbeitet wird und der erste erreichbare Zweig den Select wieder beendet, sollte das so passen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Dienstag, 17. Mai 2011 22:29
    Moderator
  • Wenn in der Select-Anweisung eine Variable steht, muss in den
    Case-Anweisungen ein Wert stehen, auf den als Inhalt dieser Variablen
    geprüft werden kann (oder auch eine Liste, ggf. auch Vergleich-Operatoren.
     
    Bei "Case Is > 0 And CInt(angle < 90)" kann der Compiler nicht erkennen, ob
    er den Wert vom Typ Double oder vom Typ Boolean ggf. mit einer impliziten
    Konvertierung (bei Option Strict Off) prüfen soll.
     
    Für solche Fälle ist es einfacher, auf True zu selektieren (geht nur in
    VB.NET):
     
    Dim angle As Double = 124.78
     
    Select Case True
    Case angle=0 OR angle=90 OR angle=180 OR angle=270
    Return 1
    Case angle > 0 And angle < 90
    Console.WriteLine("Wert > 0 und < 90")
    Case angle > 90 And angle < 180
    Console.WriteLine("eigentlich muss in diese Case-Anweisung gesprungen
    werden")
    Case angle > 180 And angle < 270
    '
    Case angle > 270 And angle < 360
    '
    End Select
     
    Zu beachten ist aber auch, dass der Typ double ggf. wegen der begrenzten
    Mantissenlänge Rundungsfehler bewirken kann und z.B. eine Prüfung auf
    angle=90 bei angle=89.99999 nicht erfolgreich sein kann. Es sollte bei
    solchen Abfragen ggf. ein epsilon für Abweichungen (Rundungen) vorgesehen
    werden.
     
    --
    Viele Grüße
    Peter
     
     
    Mittwoch, 18. Mai 2011 06:01

Alle Antworten

  • Hallo Alexander,

    Kann mir jemand sagen, warum nicht "Case Is > 90 And CInt(angle < 180)" als richtiger Case-Zweig erkannt wird?

    weils totaler Quatsch ist, was da steht? :)

    Ich weiß zwar nicht, was da wirklich bei rumkommen würde aber lies mal einfach ein wenig was zu "Is" und "And", wie Du sie hier verwendest.

      http://msdn.microsoft.com/de-de/library/kb136x1y.aspx

      http://msdn.microsoft.com/de-de/library/sdbcfyzh.aspx

    Das hat hier mit dem, was Du machen willst, nix zu tun.


    Eine Lösung könnte bspw. so aussehen:

    ---

    Select Case x
        Case 0, 90, 180, 270, 360
            ...
        Case 0 To 90
            ...
        Case 90 To 180
            ...
        Case 180 To 270
            ...
        Case 270 To 360
            ...
    End Select

    ---

    Man könnte zwar auch mit 90.00000000001 oder ähnlichem anfangen, da aber von oben nach unten gearbeitet wird und der erste erreichbare Zweig den Select wieder beendet, sollte das so passen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Dienstag, 17. Mai 2011 22:29
    Moderator
  • Wenn in der Select-Anweisung eine Variable steht, muss in den
    Case-Anweisungen ein Wert stehen, auf den als Inhalt dieser Variablen
    geprüft werden kann (oder auch eine Liste, ggf. auch Vergleich-Operatoren.
     
    Bei "Case Is > 0 And CInt(angle < 90)" kann der Compiler nicht erkennen, ob
    er den Wert vom Typ Double oder vom Typ Boolean ggf. mit einer impliziten
    Konvertierung (bei Option Strict Off) prüfen soll.
     
    Für solche Fälle ist es einfacher, auf True zu selektieren (geht nur in
    VB.NET):
     
    Dim angle As Double = 124.78
     
    Select Case True
    Case angle=0 OR angle=90 OR angle=180 OR angle=270
    Return 1
    Case angle > 0 And angle < 90
    Console.WriteLine("Wert > 0 und < 90")
    Case angle > 90 And angle < 180
    Console.WriteLine("eigentlich muss in diese Case-Anweisung gesprungen
    werden")
    Case angle > 180 And angle < 270
    '
    Case angle > 270 And angle < 360
    '
    End Select
     
    Zu beachten ist aber auch, dass der Typ double ggf. wegen der begrenzten
    Mantissenlänge Rundungsfehler bewirken kann und z.B. eine Prüfung auf
    angle=90 bei angle=89.99999 nicht erfolgreich sein kann. Es sollte bei
    solchen Abfragen ggf. ein epsilon für Abweichungen (Rundungen) vorgesehen
    werden.
     
    --
    Viele Grüße
    Peter
     
     
    Mittwoch, 18. Mai 2011 06:01