OOP Course
Сьогодні

Підрозділ 9.4

Позиційний патерн

Пояснює positional pattern для типів із деконструктором: зіставлення об'єкта за позиціями та використання отриманих значень у результаті.

9.4. Позиційний патерн

У секції 9.3 ми передавали у switch явно створений кортеж: (specialty, shift) switch. Але що якщо дані вже зібрані в об'єкт? Розбирати об'єкт на окремі змінні перед switch — зайва церемонія. Позиційний патерн вирішує це: він автоматично «розкладає» об'єкт через метод Deconstruct і потім зіставляє позиції — так само, як кортежний патерн.

Механізм: Deconstruct як міст

Щоб об'єкт підтримував позиційний патерн, він повинен мати метод Deconstruct з out-параметрами. Компілятор виконує три кроки:

  1. Викликає obj.Deconstruct(out var p1, out var p2, ...) — отримує набір out-значень.
  2. Формує з цих значень тимчасовий кортеж позицій [0], [1], [2]...
  3. Зіставляє кожну позицію з відповідним патерном у дужках (pat1, pat2, ...).

Таким чином, позиційний патерн — це кортежний патерн над об'єктом, що вміє себе деконструювати. Зв'язок між 9.3 (кортежний) і 9.4 (позиційний) прямий: вони використовують один і той самий механізм зіставлення по позиції.

Позиційний патерн: Deconstruct → кортеж → зіставлення

Зв'язок з record (8.10)

У розділі 8.10 ми дізнались, що позиційний record автоматично генерує Deconstruct. Це означає: будь-який позиційний record вже підтримує позиційний патерн без жодного додаткового коду:

public record VitalSigns(double Temperature, int Pulse, int OxygenSat);

// Позиційний патерн одразу доступний:
vitals switch
{
    (> 38.5, > 100, _)        => "Жар і тахікардія",
    (_, _, < 90)              => "Гіпоксія",
    (>= 36.0 and <= 37.0, ..) => "Норма",
    _                         => "Потрібен огляд"
}

record і позиційний патерн — природна пара: record компактно описує структуру, позиційний патерн компактно описує умови на цю структуру.

Приклад: record з позиційним патерном

У передостанньому arm (>= 36.0 and <= 37.0, < 100, >= 95) кожна позиція містить реляційний або логічний патерн. В останньому arm (var t, var p, var o2) — захоплення всіх позицій у змінні.

Кастомний Deconstruct

Якщо клас не є record, Deconstruct визначається вручну — метод без типу результату (void) з параметрами out:

Зверніть: Deconstruct розкриває лише Type і Department — не PatientName. Ми самі вирішуємо, які поля «виставити» позиційному патерну. Решту полів можна перевіряти через property pattern окремо або через var з подальшою умовою.

Порівняння: кортежний vs позиційний патерн

Аспект Кортежний (9.3) Позиційний (9.4)
Вхід явний кортеж (a, b) об'єкт з Deconstruct
Вимога будь-які два значення Deconstruct в класі/record
Зв'язок кортеж з 8.9 record з 8.10
Коли краще незалежні зовнішні значення вже є об'єкт з даними

Якщо дані вже «живуть» в об'єкті — позиційний патерн. Якщо дані приходять як окремі змінні — кортежний.

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