Instrucțiunea switch
Instrucțiunea switch/case evaluează o expresie și compară valoarea acesteia cu un set de valori. În cazul unei potriviri, execută un anumit cod.
Instrucțiunea switch are următoarea formă:
switch (expresie)
{
case valoare1:
// codul executat dacă expresia are valoarea1
break;
case valoare2:
// codul executat dacă expresia are valoarea2
break;
// .............
case valoareN:
// codul executat dacă expresia are valoareaN
break;
default:
// codul executat dacă expresia nu are niciuna dintre valorile de mai sus
break;
}
După cuvântul cheie switch în paranteze se află expresia care urmează să fie evaluată. Valoarea acestei expresii este comparată pe rând cu valorile specificate după operatorul case. Dacă se găsește o potrivire, se va executa blocul case corespunzător.
La sfârșitul fiecărui bloc case trebuie să fie plasat unul dintre operatorii de transfer: break, goto case, return sau throw. De obicei, se folosește operatorul break. Prin utilizarea acestuia, celelalte blocuri case nu vor fi executate.
Exemplu:
string name = "Tom";
switch (name)
{
case "Bob":
Console.WriteLine("Numele tău este Bob");
break;
case "Tom":
Console.WriteLine("Numele tău este Tom");
break;
case "Sam":
Console.WriteLine("Numele tău este Sam");
break;
}
În acest exemplu, instrucțiunea switch compară valoarea variabilei name cu un set de valori specificate după operatorii case. Deoarece valoarea variabilei name este șirul "Tom", se va executa blocul:
case "Tom":
Console.WriteLine("Numele tău este Tom");
break;
Astfel, pe consolă va apărea mesajul:
Numele tău este Tom
Dacă valoarea variabilei name nu se potrivește cu niciuna dintre valorile specificate după operatorii case, atunci nu se execută niciun bloc case. Totuși, dacă dorim să executăm anumite acțiuni chiar și în acest caz, putem adăuga un bloc opțional default. De exemplu:
string name = "Alex";
switch (name)
{
case "Bob":
Console.WriteLine("Numele tău este Bob");
break;
case "Tom":
Console.WriteLine("Numele tău este Tom");
break;
case "Sam":
Console.WriteLine("Numele tău este Sam");
break;
default:
Console.WriteLine("Nume necunoscut");
break;
}
În acest caz, niciuna dintre valorile specificate după operatorii case nu se potrivește cu valoarea variabilei name, deci se va executa blocul default:
default:
Console.WriteLine("Nume necunoscut");
break;
Dacă dorim ca, după executarea unui bloc case, să se execute un alt bloc case, putem folosi operatorul goto case în loc de break:
int number = 1;
switch (number)
{
case 1:
Console.WriteLine("case 1");
goto case 5; // transfer către case 5
case 3:
Console.WriteLine("case 3");
break;
case 5:
Console.WriteLine("case 5");
break;
default:
Console.WriteLine("default");
break;
}
Returnarea unei valori din switch
Instrucțiunea switch permite returnarea unei valori. Pentru returnarea unei valori în blocurile case poate fi utilizat operatorul return. De exemplu, să definim următoarea metodă:
int DoOperation(int op, int a, int b)
{
switch (op)
{
case 1: return a + b;
case 2: return a - b;
case 3: return a * b;
default: return 0;
}
}
În metoda DoOperation se transmite un cod numeric al operației și doi operanzi. În funcție de codul operației, se va efectua o anumită operație asupra operanzilor, iar rezultatul acesteia este returnat din metodă. Dacă codul operației nu este 1, 2 sau 3, atunci metoda va returna 0.
Apoi putem apela această metodă:
int DoOperation(int op, int a, int b)
{
switch (op)
{
case 1: return a + b;
case 2: return a - b;
case 3: return a * b;
default: return 0;
}
}
int result1 = DoOperation(1, 10, 5); // 15
Console.WriteLine(result1); // 15
int result2 = DoOperation(3, 10, 5); // 50
Console.WriteLine(result2); // 50
Obținerea rezultatului din switch
Deși instrucțiunea switch din exemplul anterior funcționează perfect, o putem simplifica pentru a obține rezultatul direct din instrucțiunea switch:
int DoOperation(int op, int a, int b)
{
int result = op switch {
1 => a + b,
2 => a - b,
3 => a * b,
_ => 0
};
return result;
}
Acum nu mai este necesar operatorul case, iar după valoarea comparată este plasat operatorul săgeată =>. Valoarea din partea dreaptă a săgeții servește drept valoare returnată. În locul operatorului default se folosește _. În cele din urmă, rezultatul instrucțiunii switch va fi atribuit variabilei result.
Putem returna direct rezultatul din metodă fără a atribui variabilei rezultatul instrucțiunii switch:
int DoOperation(int op, int a, int b)
{
return op switch
{
1 => a + b,
2 => a - b,
3 => a * b,
_ => 0
};
}
Sau putem face metoda și mai scurtă:
int DoOperation(int op, int a, int b) => op switch
{
1 => a + b,
2 => a - b,
3 => a * b,
_ => 0
};
Este important de menționat că această simplificare se aplică doar construcțiilor switch care returnează anumite valori, cum este în exemplul de mai sus.
De asemenea, trebuie să ne asigurăm că metoda returnează o valoare în toate cazurile posibile. De exemplu, următoarea versiune a metodei nu va funcționa:
int DoOperation(int op, int a, int b)
{
return op switch
{
1 => a + b,
2 => a - b,
3 => a * b
};
}
Această versiune a metodei returnează o valoare doar dacă codul operației este 1, 2 sau 3. Dar ce se întâmplă dacă se transmite valoarea 4 sau altă valoare? Această versiune a metodei nu se va compila.
De aceea, trebuie să prevedem returnarea unei valori din metodă în toate cazurile posibile. Putem face acest lucru adăugând un bloc default (sau _) în instrucțiunea switch, care va returna o valoare pentru toate celelalte cazuri.