Switch-Ausdruck wird nicht angenommen



  • Hi Forum,

    ich muss euch mit einer Anfängerfrage quälen und zwar: Warum wird mir meine Variable im Switch-Ausdruck nicht angenommen und bekomme als Fehlermeldung:

    Ein Switch-Ausdruck oder eine Case-Bezeichnung muss vom Typ "bool", "char", "string", "integral", "enum" sein, oder es muss sich um einen entsprechenden Typ handeln, der NULL-Werte zulässt.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace ÜSteuerbetrag
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void cmdBerechnen_Click(object sender, EventArgs e)
            {
                double x;
                x = Convert.ToDouble(txtFeld.Text);
                lblAnzeigen.Text = "";
    
                switch (x)
                {
                    case (x <= 12000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.12;
                        break;
    
                    case (x > 12000 && x <= 20000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.15;
                        break;
    
                    case (x > 20000 && x <= 30000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.20;
                        break;
    
                    case (x > 30000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.25;
                        break;   
                }
            }
        }
    }
    

    Wie ihr seht, möchte ich, dass der User sein Gehalt eingibt und aufgrund der Wertigkeit der Eingabe diese mit dem richtigen Steuersatz im Label ausgegeben wird.

    Danke für eure Mühe.

    lg Livh



  • Eventuell solltest du einfach das machen was dir der Compiler sagt und nicht mit Doubles rumprobieren 😉



  • Ich wollte nicht ausdrücken, dass ich dem compiler nicht glaube 😉

    Aber wie mache ich es, ohne, dass ich double benutzen muss bzw. mit einem der besagten Datentypen in den case-anweisungen rechnen kann?

    Wenn ich string benutze, funktioniert der switch-ausdruck, aber die case-anweisungen natürlich nicht, weil der code bei mir natürlich nicht die Zahlenwertigkeit eines strings überprüfen kann.

    lg



  • if (x <= 12000)
    


  • Danke



  • Mit einer Dictionary. So was mit switch case oder auch mit if else zu machen gehört verboten 🙂



  • OrginellerName schrieb:

    Mit einer Dictionary. So was mit switch case oder auch mit if else zu machen gehört verboten 🙂

    m(

    Zum Kote:
    Abgesehen von einigen überflüssigen using -Direktiven habe ich folgende Vorschläge:

    • Ich würde ausschließlich die Berchnung von x * 1.25 innerhalb des switches durchführen.

    Danach erst lblAnzeigen.Text = String.Format("inkl. Steuersatz: {0:C}", new CultureInfo("de-de"));

    • Anstelle von Convert.ToDouble eher Double.TryParse verwenden.
    • Zwar akzeptiert .Net Umlaute in Bezeichnern, jedoch ist das vor allem in Namespcaces (ÜSteuerbetrag) unpassend.


  • Wieso bekomme ich für meine Antwort einen Bad Smile? Wenn das überhaubt einer ist.



  • Kannst du bitte das Dictionary Beispiel einmal posten?



  • OrginellerName schrieb:

    Wieso bekomme ich für meine Antwort einen Bad Smile? Wenn das überhaubt einer ist.

    Weil der Vorschlag so gar nicht zum Thema passt und daher ein Trollrating von 9,2 auf der nach oben offenen Trollskala hat.

    Für das vom OP beschriebene Problem wäre ein Dictionary komplett ungeeignet.



  • Ist ja eigentlich nur ein Mapping der beiden Zahlen.
    Ich habe einen Bereich und einen zugehörigen Steuersatz. Das kann man dann in irgendeiner Tabellenform ablegen.

    Von mir aus eine Klasse mit zwei Werten min und max + den Setuersatz. Und dann das ganze in einer List ablegen.

    Und nun kann ich ja bequem mit Linq darüber eine Abfrage starten

    var y = list.SingleOrDefault( r => r.min < x && r.max > x)
    if( y != null )
      var value = y.rate * x
    


  • Für das vom OP beschriebene Problem wäre ein Dictionary komplett ungeeignet.

    Behauptet der Spagettiprogrammierer.

    Wenn also noch mehr Steuersätze hinzukommen erweiterst du dein switch case. Alles klar. Und wenn du die Beträge und die zugehörigen Steuersätze in einer GUI einpflegen willst, was machst du dann? Einen eintrag hier im Forum bei dem du nachfragst wie du das switch case per Code erweiterst. Du Troll.



  • Livh schrieb:

    Hi Forum,

    ich muss euch mit einer Anfängerfrage quälen und zwar: Warum wird mir meine Variable im Switch-Ausdruck nicht angenommen und bekomme als Fehlermeldung:

    Ein Switch-Ausdruck oder eine Case-Bezeichnung muss vom Typ "bool", "char", "string", "integral", "enum" sein, oder es muss sich um einen entsprechenden Typ handeln, der NULL-Werte zulässt.

    switch (x)
                {
                    case (x <= 12000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.12;
                        break;
    
                    case (x > 12000 && x <= 20000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.15;
                        break;
            }
    

    Nur mal so: Deine switch-Anweisung ist falsch eingerückt. Zwar nicht falsch, wird compiliert, aber schwer leserlich. Richtig:

    switch (x) {
                case (x <= 12000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.12;
                        break;
                case (x > 12000 && x <= 20000):
                        lblAnzeigen.Text = "inkl. Steuersatz" + x * 1.15;
                        break;
                }
    

    Die "case"-Anweisungen haben die gleichen Einrückungen wie das switch-Statement selbst (sind ja alles gleichwertige Alternativen). So ist es zumindest bei Kernighan & Ritchie und Stroustrup. Meine Klammersetzung mag man mir verzeihen - ích bevorzuge die geschweifte Klammer auf der selben Zeile wie das Statement (kann man in Visual Studio auch einstellen :-), wie in K&R und Stroustrup.

    Deine switch-Anweisung kann IMHO deshalb schon nicht fuktionieren, da x ein double ist, die case-Anweisungen also ein double erwarten, aber ein bool (x <= ...) zurückkommt. In C/C++ gehen bei case IMO sowieso nur int-Werte. Bei C# und Java kann man zwar auch andere Typen verwenden, dann geht aber der Geschwindigkeitsvorteil verloren und man könnte (so macht man es in C/C++) gleich

    if (something)
    else if (something other) {
    ...
    }
    else if (another thing) {
    ...
    }
    else
    doSomething();

    verwenden.

    Die switch-Anweisung in C/C++ ist ja gerade so schnell, weil sie nur ganzzahlige Werte abfragen muss (und somit eine Sprungtabelle aufbauen kann). Verwendet man sie so wie Du, kann man genau so gut if... else if... else if...

    verwenden.

    BTW: Fortran ist teilweise so viel schneller, weil es die DO-Schleife hat, die nur auf den ersten Blick wie die for-Schleife in den C-Sprachen ist. Bei der Fortran-DO-Schleife wird die Wiederholungsanzahl am Anfang einmal berechnet und kann nicht wie in den C-Sprachen (Java) bei for() (der Index) innerhalb der Schleife verändert werden.



  • johann schrieb:

    Nur mal so: Deine switch-Anweisung ist falsch eingerückt. Zwar nicht falsch, wird compiliert, aber schwer leserlich. Richtig:

    Nun ja. Alles was du da präsentierst ist viel unleserlicher als das was der Threadstarter präsentiert.

    johann schrieb:

    Deine switch-Anweisung kann IMHO deshalb schon nicht fuktionieren, da x ein double ist, die case-Anweisungen also ein double erwarten, aber ein bool (x <= ...) zurückkommt.

    So weit waren wir schon.



  • johan schrieb:

    Nur mal so: Deine switch-Anweisung ist falsch eingerückt.

    Nein, ist sie nicht. Egal welchen Stil man verwendet: Solange man konsequent ist, ist das in Ordnung.

    Es gibt nicht einen Stil, und der von ihm verwendete ist durchaus nicht unüblich (Ich kenne ihn sogar aus den Firmen in denen ich gearbeitet habe nicht anders, auch wenn mir dein Stil nicht unbekannt ist - vor allem aus der Unix-Richtung). Deinen Stil finde ich persönlich wesentlich unleserlicher.



  • Schön das wir das nun geklärt haben mit dem switch case.

    Trotzdem ist das ganze über switch case oder auch if else zu machen alles andere als schön. Auch wenn es hier keiner wahr haben will.



  • OrginellerName schrieb:

    Trotzdem ist das ganze über switch case oder auch if else zu machen alles andere als schön. Auch wenn es hier keiner wahr haben will.

    Du hast noch nicht demonstriert wie du dir das mit einem Dictionary umsetzen willst. Korrigiere mich wenn ich mich irre, aber das Dictionary arbeitet mit Schlüssel/Werte-Paaren, und nicht mit Bereichen.

    Wenn er mit Bereichen wie 12000..20000 für einen Wert arbeitet, hilft hier imho kein Dictionary, dies ist tatsächlich aus meiner Sicht ein Anwendungsfall für if/else-Cascaden (und auch switch ist nicht für Bereiche geeignet).



  • Dieses Linq-Konstrukt da oben, bzw. die darin vorkommente Liste, nennt er Dictionary. Mit einem richtigen Dictionary geht es nicht, was gibts da noch zu diskutieren.



  • Oh man. Das war ja nun nur noch vereinfachter. Klar kann man das auch mit einer Dictionary machen.

    Ich kann ja auch den key der Dictionary als klasse definieren die einen Bereich hat.

    Aber du hast recht was gibts da noch zu diskutieren. Wollte ja nur auf eine bessere Lösung hinweisen als das mit dem ganzen switch case Gewurschtele. Aber der fragende ist sicher schön längst ausgestiegen.



  • OrginellerName schrieb:

    Wollte ja nur auf eine bessere Lösung hinweisen als das mit dem ganzen switch case Gewurschtele. Aber der fragende ist sicher schön längst ausgestiegen.

    Ich bin noch da, konnte aber dann nicht mehr mitreden, weil mir das nötige know-how fehlt. Habe inzwischen auf switch-case verzichtet und If verwendet.

    Danke euch vielmals für eure Mühe 😉


Log in to reply