OOP Course
Сьогодні

Підрозділ 9.5

Реляційний та логічний патерни

Розглядає relational і logical patterns: порівняння через <, <=, комбінування умов через and/or та заперечення через not.

9.5. Реляційний та логічний патерни

У попередніх секціях патерни порівнювали значення на рівність: "Active", true, null. Але в медицині (та загалом у числовій логіці) рішення ухвалюються на основі діапазонів: температура вище 38.5°C — жар; тиск від 140 — гіпертонія. Для цього у C# 9 введено реляційний та логічний патерни.

Реляційний патерн

Реляційний патерн (relational pattern) перевіряє значення за допомогою операторів <, >, <=, >=:

temperature switch
{
    < 36.0  => "Гіпотермія",
    >= 38.5 => "Жар",
    _       => "Норма"
}

Важливо: реляційний патерн не є оператором порівняння. Це патерн — тобто він може стояти не лише у switch, а й після is, у позиції кортежного патерну, всередині патерну властивостей тощо:

if (temperature is > 38.5) { ... }          // після is
(temp, pulse) switch { (> 38.5, > 100) => } // в позиції кортежу
{ Priority: >= 3 }                           // в патерні властивостей

Реляційний патерн: температура тіла — діапазони та рішення

Логічний патерн: and, or, not

Логічний патерн дозволяє комбінувати кілька патернів через and, or, not. Ключова особливість: and, or, not тут — це патернні оператори, а не логічні оператори &&, ||, !.

Різниця принципова:

  • && і || — оператори над булевими значеннями: x > 5 && x < 10
  • and і or у патернах — оператори над патернами: > 5 and < 10
// Звичайна умова (bool-вирази):
if (temp > 37.5 && temp < 39.0) { ... }

// Логічний патерн (комбінація патернів):
if (temp is > 37.5 and < 39.0) { ... }

Результат той самий, але форма запису в switch є значно виразнішою.

Пріоритет: and вищий за or, як множення вище за додавання. Для явного групування використовуйте дужки:

// (< 35 or > 39) — критичні значення
temperature is < 35 or > 39

// not (>= 36 and <= 37) — не нормальна
temperature is not (>= 36.0 and <= 37.0)

Реляційний патерн у клінічному сценарії

Кожен arm покриває рівно один інтервал, і разом вони покривають всю числову вісь. Компілятор аналізує вичерпність: якщо _ відсутній і є непокриті значення — попередження.

Логічний патерн: and, or, not у дії

not з типовим патерном

not може заперечувати не лише реляційні вирази, а й типові патерни:

if (staff is not Doctor)
    Console.WriteLine("Не лікар — не може виписувати рецепти");

// В switch:
string role = staff switch
{
    not null and not Doctor => "Медперсонал (не лікар)",
    Doctor doc              => $"Лікар: {doc.Specialty}",
    null                    => "Відсутній"
};

not null — це патернний еквівалент перевірки != null. Компілятор трактує його як null-check pattern і може застосовувати null-state analysis.

Де можна використовувати реляційні та логічні патерни

Реляційні та логічні патерни не прив'язані до switch — вони можуть стояти у будь-якому місці, де стоїть патерн:

// Після is:
if (temperature is >= 37.5 and < 39.5) { ... }

// В позиції кортежного патерну:
(temp, pulse) switch { (>= 37.5, > 100) => "..." }

// В патерні властивостей:
patient is { Age: > 60 and < 90, Priority: >= 3 }

// Навіть у декларативному присвоєнні:
bool isFever = temperature is >= 37.5;

Саме ця композиційність — можливість вкладати патерни один в одний — є головною силою pattern matching у C#.

Розроблено Tomka Yurii · © 2026 ·