Switch-Ausdruck wird nicht angenommen



  • 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 😉



  • OrginellerName schrieb:

    Oh man. Das war ja nun nur noch vereinfachter.

    Aber zu weit vereinfacht.

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

    Dann mach doch mal. Du müsstest sowas ja schon fertig herumliegen haben, immerhin meinst du ja es sollte "verboten" werden, das überhaupt anders zu lösen.

    Aber du hast recht was gibts da noch zu diskutieren.

    Das bezieht sich darauf, dass deine Listenlösung dein "Dictionary" sein soll. Ich mag keine Wortklaubereien und versuche gerne solche Diskussionen abzuwürgen.



  • Jetzt mal im ernst. Würdet ihr das wirklich über if else cascaden lösen. Was ist wenn ich die Werte über eine Oberfläche einpflegen will?



  • OrginellerName schrieb:

    Jetzt mal im ernst. Würdet ihr das wirklich über if else cascaden lösen. Was ist wenn ich die Werte über eine Oberfläche einpflegen will?

    Wenn die Bereiche fest sind ja. Du bist noch deine Lösung für eine Alternative Schuldig. Es gibt Möglichkeiten, aber ein Dictionary sehe ich da nicht als Lösungsansatz an.

    Wenn auch C++ und nicht C#: Wir haben in unserer Software flexible Wertebereiche die vom Benutzer definiert werden. Diese liegen sortiert in einem Vector (Immer mit einem Schwellenwert ab wann oder alternativ bis wann der Eintrag gilt) und diese werden beim ermitteln durchiteriert; eine Lösung über eine Dictionary (in C++: map) bei dem die Geschwindigkeitsvorteile desselben nicht wieder zunichte gemacht werden, sehe ich nicht. Ich will auch erst einmal sehen wie du einen Range-Key definieren willst, bei dem du anschließend nicht manuell suchen musst.



  • using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace TaxApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                var taxlist = new Dictionary<PayRange, Tax>
                                  {
                                      {new PayRange {Min = 0.00,     Max = 12000.00}, new Tax {Rate = 1.12}},
                                      {new PayRange {Min = 12000.01, Max = 20000.00}, new Tax {Rate = 1.15}},
                                      {new PayRange {Min = 20000.01, Max = 30000.00}, new Tax {Rate = 1.20}},
                                      {new PayRange {Min = 30000.01, Max = 99999.00}, new Tax {Rate = 1.25}}
                                  };
    
                Console.Write("Bitte Gehalt eingeben: ");
    
                var pay = Convert.ToDouble(Console.ReadLine());
    
                Console.Write("Steuersatz: ");
                Console.WriteLine(taxlist.SingleOrDefault(t => t.Key.Max >= pay && pay >= t.Key.Min).Value.Rate);
    
                Console.ReadKey();
    
            }
        }
    
        internal class Tax
        {
            public double Rate { get; set; }
        }
    
        internal class PayRange
        {
            public double Min { get; set; }
            public double Max { get; set; }
        }
    }
    


  • Hast du auch ein Beispiel, bei dem du das schnelle Suchen im Dictionary ausnutzt, und nicht nur wie bei einer Liste drüberiterierst?



  • OrginellerName schrieb:

    ...

    asc schrieb:

    ... eine Lösung über eine Dictionary (in C++: map) bei dem die Geschwindigkeitsvorteile desselben nicht wieder zunichte gemacht werden...

    Ganz davon abgesehen das ich deine Lösung als problematisch ansehe (Thema Double-Vergleich), und deine Bereiche auch nicht direkt aneinander Grenzen (Ich würde daher mit einem Wert - entweder "ab" oder "bis" arbeiten, nicht mit 2 Werten).



  • Kein Thema das mit dem double Vergleich. Mann kann hier noch vieles verbessern. Und keiner hat gesagt, dass ich Geschwindikkeitsvorteile habe mit der Dictionary. Aber viel sauberere als die if else Lösung. Und leicht erweiterbar.

    Ihr habt mir immer noch nicht verraten wie ihr das if else Konstrukt erweitert wenn ihr die Werte per GUI pflegen wollt.


Anmelden zum Antworten