Relační, logické a uzávorkované vzory

Tip

Tento článek je součástí části Základy pro vývojáře, kteří už znají aspoň jeden programovací jazyk a učí se jazyk C#. Začněte přehledem porovnávání vzorů , pokud jsou pro vás vzory nové. Kompletní jazyková pravidla najdete v referenčních informacích k relačním vzorům a logickým vzorům .

Relační a logické vzory popisují rozsahy, alternativy a vyloučení. Následující metoda je kombinuje ke klasifikaci teploty:

static string ClassifyTemperature(int temperature) =>
    temperature switch
    {
        < 0 => "Below freezing",
        >= 18 and <= 24 => "Comfortable",
        (>= 0 and < 10) or > 30 => "Far outside the comfortable range",
        _ => "Cool or warm"
    };

Výraz temperature je vstup vzoru. Jazyk C# ji vyhodnotí pouze jednou a každá větev příkazu switch otestuje výslednou hodnotu. Zbraně demonstrují tyto testy:

  • < 0 testuje jednu mezní hodnotu.
  • >= 18 and <= 24 testuje rozsah hodnot.
  • (>= 0 and < 10) or > 30 testuje dva alternativní rozsahy.

Tento článek ukazuje vzory i imperativní podmínky, abyste se mohli naučit jednotlivé formuláře a porovnat, jak vyjadřují stejná rozhodnutí. Jedna podmínka může vypadat podobně v obou podobách. Vzory můžou usnadnit čtení řady souvisejících větví tím, že si zachovávají volby vedle výsledků. Zvolte takovou podobu, aby byl kód co nejsrozumitelnější.

Porovnání hodnot s relačními vzory

Relační vzor porovnává vstup vzoru s konstantou známou v době kompilace pomocí operátorů <, >, <= nebo >=. Konstanta doby kompilace je hodnota, kterou kompilátor může vyhodnotit při kompilaci programu. Číselné a znakové literály a const proměnné kompatibilních číselných nebo znakových typů představují reprezentativní příklady. Běžné proměnné, vlastnosti, volání metod a pole static readonly nejsou konstanty v době kompilace. V úvodním příkladu testují >= 18 i temperature stejnou vyhodnocenou hodnotu <= 24.

Stejný relační symbol se může objevit v běžném výrazu nebo ve vzoru. Následující příklad používá obě podoby s teplotou:

static void ShowExpressionAndPattern(int temperature, int threshold)
{
    bool belowThreshold = temperature < threshold;
    bool belowFreezing = temperature is < 0;

    string description = temperature switch
    {
        < 0 => "Freezing",
        0 => "Freezing point",
        > 0 => "Above freezing"
    };

    Console.WriteLine(
        $"Below threshold: {belowThreshold}; " +
        $"below freezing: {belowFreezing}; {description}");
}

temperature < threshold je relační výraz. Vyhodnocuje oba operandy a vytváří bool. Kterýkoli z operandů může být nekonstantním výrazem.

V části temperature is < 0 je temperature vstupní výraz vzoru. Jazyk C# ji vyhodnocuje a relační vzor < 0 testuje výslednou hodnotu. V části switch < 0 => "Freezing" výraz před switch poskytuje vstup, takže vzor obsahuje pouze < 0.

Výraz může porovnat temperature s proměnnou threshold. Operand relačního vzoru musí být konstanta kompilačního času, proto použijte relační výraz, pokud je hodnota porovnání proměnnou. Pokud je porovnávaná hodnota konstantní, může fungovat kterákoli z obou variant.

Pokud je pravý operand konstantní, zvolte hlavně pro čitelnost. Relační výraz často odpovídá jednomu přímému porovnání. Relační vzor lze kombinovat s jinými vzory a přirozeně se hodí tam, kde několik rozsahů odpovídá výsledkům switche.

Kombinování podmínek s logickými vzory

Logické vzorce kombinují nebo negují vzorce pomocí operátorů vzorců and, or a not:

  • Vzor and se shoduje, když se oba vnořené vzory shodují.
  • Vzor or odpovídá, když se shoduje některý z vnořených vzorů.
  • Vzor not je úspěšný, když jeho vnořený vzor selže.

V úvodním příkladu se používá and popis rozsahu a or k popisu alternativ. Vzor not může vyloučit hodnotu, jako v status is not Status.Complete. Následující metody zobrazují oba formuláře, abyste se mohli naučit jejich syntaxi a porovnat, jak vyjadřují stejný test:

static bool IsWeekendPattern(DayOfWeek day) =>
    day is DayOfWeek.Saturday or DayOfWeek.Sunday;

static bool IsWeekendImperative(DayOfWeek day) =>
    day == DayOfWeek.Saturday || day == DayOfWeek.Sunday;

Tvar vzoru používá dva konstantní vzory spojené pomocí or. Imperativní formulář používá dva výrazy rovnosti spojené podmíněným operátorem ||OR . Oba formuláře jsou stručné a jasné pro tuto jedinou podmínku. Zvolte formulář, který nejlépe odpovídá okolnímu kódu. Vzory často objasňují několik souvisejících voleb v switch, jako v úvodním příkladu.

Operátory vzorů tvoří vzory místo logických výrazů: and odpovídá spojení vzorů, or alternativám vzorů a not negaci vzorů. Logické výrazy používají &&, ||a !. Zvolte or , kdy má několik alternativ vzorů stejný výsledek. Volba not při vyjádření vyloučeného vzoru je jasnější než výpis všech přijatých hodnot.

Seskupit vzory pomocí závorek

Uzávorkovaný vzor používá závorky k určení nebo změně seskupení vnořených vzorů. Vazba určuje, který vzor operandů operátor seskupí dohromady, podobně jako implicitní seskupení, když nezapisujete závorky. Jazyk C# určuje následující pořadí vazeb:

  1. not
  2. and
  3. or

Následující test přijímá priority 1 až 3 nebo zvláštní prioritu 9:

static bool IsAcceptedPriority(int priority) =>
    priority is (>= 1 and <= 3) or 9;

Kompilátor seskupí and před or. Závorky umožňují explicitní seskupení a dvě alternativy snadno vidět: rozsah od 1 do 3 nebo 9. Pro čitelnost používejte závorky vždy, když se vzor promíchá and a ornebo pokud not se vztahuje na složený vzor. Závorky mohou také změnit výchozí seskupení, jako v not (>= 1 and <= 3).

Pořadí kontroly modulu runtime pro vnořené vzory není zadané a operátory vzorů místo logických pravidel s krátkým okruhem dodržují pravidla porovnávání vzorů. Pište vnořené vzory tak, aby jejich výsledek byl nezávislý na pořadí kontrol.

when Použití ochrany pro samostatnou podmínku

Logické vzory fungují nejlépe, když vnořené vzory popisují samotnou vstupní hodnotu. Stráž when je další booleovská podmínka u návěští case nebo větve příkazu switch. Ochranu použijte, když rozhodnutí také závisí na informacích oddělených od vstupu vzoru.

Následující upozornění závisí na teplotě a samostatné isOutdoors hodnotě:

static string GetHeatWarning(int temperature, bool isOutdoors) =>
    temperature switch
    {
        > 35 when isOutdoors => "High heat outdoors",
        > 35 => "High heat",
        _ => "No heat warning"
    };

Relační vzor > 35 popisuje temperature vstup. when isOutdoors Stráž kontroluje samostatnou hodnotu. Guard je také vhodnější, když podmínka vyžaduje volání metody nebo booleovský výraz, který syntaxe vzorů nevyjadřuje jasně.

Relační a logické vzory používejte, když usnadňují zobrazení povolených obrazců nebo hodnot vstupu, zejména mezi několika přepínacími rameny. Použijte booleovský výraz, pokud jednodušeji vyjadřuje přímou podmínku. when Ochranu použijte, když volba přepínače závisí na samostatné hodnotě nebo na podmínce lépe vyjádřené jako logický výraz.

Viz také