V rámci vykonávání programu je v některých případech potřebné provést část kódu pouze pokud platí podmínka. Například pokud je rezervace pobytu uskutečněna mezi 10. a 12. hodinou, pak je aplikována dodatečná 10% sleva.

K tomuto slouží v programech větvení, které lze rozdělit na dva typy:

  • Větvení do dvou větví – používáme if, případně if-else
  • Větvení do více větví – používáme switch

If Else

Větvení pomocí if se využívá ve chvíli, kdy je potřeba zajistit, že se část kódu provede pouze pokud je splněna podmínka. Volitelně je možné za if umístit i else, jehož obsah se provede když podmínka neplatí.

Do kulatých závorek za if je možné umístit cokoliv, co lze vyhodnotit na pravdivostní hodnotu (boolean). Typicky se zde umisťuje boolean proměnná nebo výraz (např. porovnání dvou čísel: x < 7)

Syntaxe if-else

if (podmínka)
{
    // Pokud je podmínka vyhodnocena jako true
}
else
{
   // Jinak
}

Podmínky lze za sebe řetězit a zároveň i do sebe vnořovat. Následující kódy jsou ekvivalentní.

if (isUserLoggedIn)
{
	// Proveď pokud je uživatel přihlášen
 
    if (hasAdminRights)
    {
        // Proveď akci dostupnou pouze pro administrátory, kteří jsou přihlášeni
    }
}
 
// Je ekvivalentní s tímto kratším zápisem:
if (isUserLoggedIn && hasAdminRights)
{
    // Proveď akci dostupnou pouze pro přihlášené administrátory
}
if (isUserLoggedIn)
{
    // Zobraz přihlašovací obrazovku
}
else
{
    if (isGuest)
    {
        // Zobraz omezený přístup pro hosta
    }
}
 
// Je ekvivalentní s tímto kratším a přehlednějším zápisem:
if (isUserLoggedIn)
{
    // Zobraz přihlašovací obrazovku
}
else if (isGuest)
{
    // Zobraz omezený přístup pro hosta
}
 

Rozhodovací příkazy

Úplný rozhodovací příkaz

  • umožňuje provádět nějaké příkazy, pokud podmínka platí a jiné příkazy pokud podmínka neplatí
    • Obsahuje if-else

Neúplný rozhodovací příkaz

  • umožňuje provádět nějaké příkazy, pokud podmínka platí
    • Obsahuje pouze if

Omezení zanoření

Kód, ve kterém dochází k násobnému zanořování if je velmi obtížně čitelný a vždy je potřebné se tomu pokusit vyhnout. Velmi efektivním způsobem je minimalizovat počet else a u if spíše kontrolovat, že podmínka není splněna, a pak ukončit metodu.

Cílem je se pokusit o udržení “hlavní logiky” (tzn. business logiky aplikace, ne validace) co nejméně zanořené.

Příklad s hlubokým zanořením:

void ProcessOrder(Order order)
{
    if (order != null)
    {
        if (order.IsPaid)
        {
            if (order.Items.Count > 0)
            {
                if (UserHasPermission(order.User))
                {
                    // Zpracování objednávky
                    ShipOrder(order);
                }
                else
                {
                    Console.WriteLine("Uživatel nemá oprávnění.");
                }
            }
            else
            {
                Console.WriteLine("Objednávka neobsahuje položky.");
            }
        }
        else
        {
            Console.WriteLine("Objednávka není zaplacená.");
        }
    }
    else
    {
        Console.WriteLine("Objednávka je null.");
    }
}

Vylepšená verze:

void ProcessOrder(Order order)
{
    if (order == null)
    {
        Console.WriteLine("Objednávka je null.");
        return;
    }
 
    if (!order.IsPaid)
    {
        Console.WriteLine("Objednávka není zaplacená.");
        return;
    }
 
    if (order.Items.Count == 0)
    {
        Console.WriteLine("Objednávka neobsahuje položky.");
        return;
    }
 
    if (!UserHasPermission(order.User))
    {
        Console.WriteLine("Uživatel nemá oprávnění.");
        return;
    }
 
    // Hlavní logika bez vnoření
    ShipOrder(order);
}

Switch

Switch je využíván v případě, že je potřebné rozdělit tok programu do více větví na základě jednoho výrazu, který je umístěn v kulatých závorkách. Na začátku dojde k vyhodnocení tohoto výrazu a k výběru case s kódem, který se má vyhodnotit.

Výraz v kulatých závorkách se označuje jako selektor větvení a je vždy stejného datového typu jako hodnoty v jednotlivých case. Za klíčovým slovem case musí následovat konstanta ordinálního datového typu (int, char, enum…) a zároveň musí být každá hodnota unikátní.

Pokud case obsahuje alespoň jeden příkaz, tak je nutné, aby byl case zakončen pomocí break. Pokud však žádný příkaz neobsahuje, je možné break vynechat a dochází k tzv. propadávání fall-through tedy, že více case sdílí jeden kód.

Nakonec switch je možné umístit default blok, který je nepovinný a umožňuje přidat kód, který se vyhodnotí pokud hodnota selektoru větvení neodpovídá na žádný case.

Syntaxe switch

switch (selektor_vetveni)
{
	case A:
		// Pokud se selektor vetveni vyhodnoti na A
		break;
	default:
		// Pokud neodpovida zadny predchozi case
		break;
}

Ukázka

int cislo = 2;
 
switch (cislo)
{
	case 1: // Ilustrace propadávání.
	case 2:
		Console.WriteLine("Case 1 nebo 2");
		break;
	case 3:
		Console.WriteLine("Case 3");
		break;
	default:
		Console.WriteLine("Výchozí case");
		break;
}

Switch Expression

V případech, kdy cílem jednotlivých case je pouze vybrat jednu hodnotu, s kterou program dále pracuje, je možné využít zkrácenou syntaxi s názvem switch expression.

int number = 1;
 
string message = number switch
{
	1 => "You entered 1.",
	2 => "You entered 2.",
	_ => "Invalid input." // Slouží jako default case
};
 
Console.WriteLine(message);