C# Console "Switch Case Anweisung mit Umwandlung"

Michael-D

Cadet 3rd Year
Registriert
Nov. 2023
Beiträge
35
Guten Abend :)
und wieder mal eine Frage an die Profis...

Es gibt ja mehrere Möglichkeiten, die Auswahl einer Console über eine Taste [1] [2] [3] auszuwählen..
  1. If Else Anweisung
  2. Switch Case Anweisung
  3. DO / While mit Switch Case Kombination
Zu Punkt 1: Hab mittlerweile herausgefunden, das - bei zu vielen Abfragen, dieser Weg zu unübersichtlich ist. Bei den Möglichkeitender 3 Tastenabfragen hier natürlich nicht.

Zu Punkt 2: Ist für mich eigentlich so der eleganteste und übersichtlichste Weg, um so etwas zu machen.

Nun kommt meine Frage: Wenn man zum Beispiel wie oben, Tasten auswertet, nimmt man doch diesen Weg...

PHP:
System.Console.WriteLine("Programm  1");
System.Console.WriteLine("Programm  2");
System.Console.WriteLine("Programm  3");
System.Console.WriteLine("Nummer 1 - 3 wählen...");

string OptionSelect // Variable deklarieren
OptionSelect = Console.ReadLine(); // Variable als Benutzereingabe deklarieren

   switch (OptionSelect)
   {
      case 1:
      // Programm 1
      break;
   }

   {
      case 1:
      // Programm 2
      break;
   }

   {
      case 1:
      // Programm 3
      break;
   }

Nun gibt es aber zur Auswertung noch eine Möglichkeit...
PHP:
int OptionSelect = Convert.ToInt32(Console.ReadLine());

switch (OptionSelect)
...
Hier wird die Zahl einer Zeichenkette aus der Benutzereingabe "Console.ReadLine();" in eine Ganzzahl umgewandelt ! Stimmt das alles soweit?

Ich habe irgendwo mal gelesen (weiß aber nicht mehr wo das war), das man den letzten Weg tunlichst vermeiden sollt, wenn es geht.
Warum ist das eigendlich so? Hat die Umwandlung was mit der Rechenleistung zu tun, was da vermieden werden soll? Also im heutigen zeitalter von GHz und tonnweisen GB Speicher sollte das do ch eigentlich nicht das problem sein, oder irre ich mich da?

Danke vorab für Eure Antwort :D
 
Na ja, dein Code wird so nicht funktionieren:
  • deine geschweifte Klammern gehen so nicht, mit erstem "}" ist deine Switch-Anweisung vorbei
  • case 1, case1, ... gehören als case 1, case 2 in die erste geschweifte Klammer
  • Bzgl. Int-Konvertierung, was ist wenn einer "eins" eingibt -> kann nicht zu Int konvertiert werden, dann wird eine "FormatException" geworfen. Wenn du die nicht abfängst crasht dein ganzes Programm
  • Lösung könnte sein, zu erst mit "Regex" überprüfen ob dein "String" überhaupt in eine Zahl konvertiert werden kann
  • mit "Rechenleistung" hat solch eine Konvertierung überhaupt nichts zu tun, ist Pipifax
Wenn du wirklich nur 1, 2, 3 abfragen willst würde ich dir "ReadKey" empfehlen, hat den grossen Vorteil es braucht kein zusätzliches "Enter":

Code:
var key = Console.ReadKey();
if (key.Key == ConsoleKey.1) ...

Gibt sicher etliche YouTube-Videos, welche dir weiterhelfen können ...
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
Du verwendest die Case Anweisung als wäre Option ein Int aber es handelt sich um einen String:

C#:
switch OptionSelect
{
   case "1":
      // TODO...
     break;
   case "2":
     // TODO...
     break;
   default:
     Console.WriteLine("Eingabe pruefen...");
     break;
}
 
1. Würde ich Console.ReadKey verwenden.
2. Würde ich int.TryParse verwenden um die Eingabe zu prüfen
  • Wenn false -> Abbruch
  • Wenn true -> Weiter machen
3. Switch Expression verwenden falls Deine Programm-Aufrufe was zurückgeben

Den Default-Leg brauchst Du trotzdem wenn eine Zahl eingegeben wurde die nicht per case abgefragt wird.

ReadKey funktioniert auch nur bei einer Programmanzahl von 0-9 (weil ein Key). Ansonsten Console.ReadLine mit der gleichen int.TryParse Prüfung
 
Mit Speicher und Performance hat das eher weniger zu tun. Der int wäre beim anschließenden Switch Block sogar performanter als ein String Vergleich.
Das einzige Problem sehe ich bei Fehleingaben. Ohne Fehlerhandling kann Dein Programm abstürzen.
 
Hm, weiß nicht wieso Fehleingaben ein Problem sein sollen... die kann man doch als erstes prüfen.
Also sowas hier sollte doch funktionieren (schnell runtergeklöppelt):

static class Program { public static void Main(string[] args) { Console.WriteLine("Start"); var foo = Console.ReadKey().KeyChar.ToString(); var pg = int.TryParse(foo, out var zahl) ? ProgramCall(zahl) : GaveUp(); Console.WriteLine($"Finished with {pg}"); Environment.Exit(1); } private static readonly Func<bool> GaveUp = () => { Console.WriteLine("Eingabe war Käse"); return false; }; private static readonly Func<int, bool> ProgramCall = value => value switch { 0 => InnerProgramCall("Word"), 1 => InnerProgramCall("Excel"), 2 => InnerProgramCall("Powerpoint"), _ => DefaultLeg() }; private static readonly Func<bool> DefaultLeg = () => { Console.WriteLine("Zahl nicht mit Programm verknüpft"); return false; }; private static readonly Func<string, bool> InnerProgramCall = programPath => { //Executable Call Console.WriteLine(programPath); return true; }; }

P.S. bin zu doof für vernünftige Code-Formatierung in dem Forum.
 
Das beste Design ist immer noch wenn man dem Benutzer erst keine Falscheingabe erlaubt.
Das hier funktioniert mit Pfeiltasten und Enter/Escape:
C#:
class Program
{
    static void Main(string[] args)
    {
        int auswahl = 1;
        while (true)
        {
            Console.SetCursorPosition(0, 0);
            WriteLine("Auswahl:");
            WriteLine(" Program 1", auswahl == 1);
            WriteLine(" Program 2", auswahl == 2);
            WriteLine(" Program 3", auswahl == 3);
            var key = Console.ReadKey(true).Key;
            if (key == ConsoleKey.UpArrow && auswahl > 1) --auswahl;
            else if (key == ConsoleKey.DownArrow && auswahl < 3) ++auswahl;
            else if (key == ConsoleKey.Enter) break;
            else if (key == ConsoleKey.Escape)
            {
                Console.WriteLine("Abgebrochen!");
                return;
            }
        }
        Console.WriteLine("Auswahl ist " + auswahl);
    }

    static void WriteLine(string text, bool markiert = false)
    {
        var fc = Console.ForegroundColor;
        var bc = Console.BackgroundColor;
        Console.ForegroundColor = markiert ? bc : fc;
        Console.BackgroundColor = markiert ? fc : bc;
        Console.Write(text);
        Console.ForegroundColor = fc;
        Console.BackgroundColor = bc;
        // Löschen von altem Text:
        Console.WriteLine(new string(' ', Console.WindowWidth - text.Length));
    }
}
 
  • Gefällt mir
Reaktionen: sandreas, Michael-D, f00bar und eine weitere Person
michi.o schrieb:
Das beste Design ist immer noch wenn man dem Benutzer erst keine Falscheingabe erlaubt.
Dieses.

Allerdings wird hier "Idiotensicherheit" mit etwas umständlicherer Eingabe erkauft. Entweder man bedient sich des Prinzip der "Hotkeys" oder eben nicht. Es gibt quasi immer einen Tradeoff.
 
  • Gefällt mir
Reaktionen: Michael-D
TomWoB schrieb:
Na ja, dein Code wird so nicht funktionieren:
  • deine geschweifte Klammern gehen so nicht, mit erstem "}" ist deine Switch-Anweisung vorbei
  • case 1, case1, ... gehören als case 1, case 2 in die erste geschweifte Klammer
Ja, ich weiß. Hab ich gestern nur zu schnell hier geschrieben ;)

TomWoB schrieb:
  • Lösung könnte sein, zu erst mit "Regex" überprüfen ob dein "String" überhaupt in eine Zahl konvertiert werden kann
Das ist ja interessant. Also das hier was Sie meinen? Identifizieren, ob eine Zeichenkette eine Zahl ist Das werde ich mir mal genauer ansehen. Danke nochmals ;)

  • mit "Rechenleistung" hat solch eine Konvertierung überhaupt nichts zu tun, ist Pipifax
Ah Ok. Das macht Sinn. Aber da sieht man mal wieder, was man so alles in einigen Foren liest.

TomWoB schrieb:
Wenn du wirklich nur 1, 2, 3 abfragen willst würde ich dir "ReadKey" empfehlen, hat den grossen Vorteil es braucht kein zusätzliches "Enter":


Code:
var key = Console.ReadKey();
if (key.Key == ConsoleKey.1) ...
Genau darauf bin ich heute morgen auch drauf gekommen. Danke trotzdem ;)
Ergänzung ()

michi.o schrieb:
Das beste Design ist immer noch wenn man dem Benutzer erst keine Falscheingabe erlaubt.
Das hier funktioniert mit Pfeiltasten und Enter/Escape:
Absoluter Wahnsinn!!! Das wäre nämlich die nächste Frage gewesen. Warum? Ich hatte mich schon seit einiger Zeit gefragt, warum man in einer Console keine Farbattribute setzten kann. Dann hab ich mich mal auf die Suche gemacht und unter Easy Console oder Konsolengesteuerte GUI gefunden, die ich mir nächste Woche mal anschauen wollte. Und dann hab ich genau das gefunden...

PHP:
 var fc = Console.ForegroundColor;
 var bc = Console.BackgroundColor;

Und der Rest mit der Cursorsteuerung ist genau das, was ich auch noch so untersuchen will.

Vielen Dank für diese wertvolle Info!
 
Zuletzt bearbeitet:
Gretzki schrieb:
private static readonly Func<bool> GaveUp = () =>
private static readonly Func<int, bool> ProgramCall = value => value switch
private static readonly Func<bool> DefaultLeg = () =>
@Gretzki Wie ist der Stil, möglichst durchgehend mit Delegates zu arbeiten, eigentlich entstanden - einfach der Flexibilität zuliebe, oder asynchrones Ausführen oder .. ?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
Zurück
Oben