Підрозділ 9.4
Позиційний патерн
Пояснює positional pattern для типів із деконструктором: зіставлення об'єкта за позиціями та використання отриманих значень у результаті.
9.4. Позиційний патерн
У секції 9.3 ми передавали у switch явно створений кортеж: (specialty, shift) switch. Але що якщо дані вже зібрані в об'єкт? Розбирати об'єкт на окремі змінні перед switch — зайва церемонія. Позиційний патерн вирішує це: він автоматично «розкладає» об'єкт через метод Deconstruct і потім зіставляє позиції — так само, як кортежний патерн.
Механізм: Deconstruct як міст
Щоб об'єкт підтримував позиційний патерн, він повинен мати метод Deconstruct з out-параметрами. Компілятор виконує три кроки:
- Викликає
obj.Deconstruct(out var p1, out var p2, ...)— отримує набірout-значень. - Формує з цих значень тимчасовий кортеж позицій
[0],[1],[2]... - Зіставляє кожну позицію з відповідним патерном у дужках
(pat1, pat2, ...).
Таким чином, позиційний патерн — це кортежний патерн над об'єктом, що вміє себе деконструювати. Зв'язок між 9.3 (кортежний) і 9.4 (позиційний) прямий: вони використовують один і той самий механізм зіставлення по позиції.

Зв'язок з 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 |
| Коли краще | незалежні зовнішні значення | вже є об'єкт з даними |
Якщо дані вже «живуть» в об'єкті — позиційний патерн. Якщо дані приходять як окремі змінні — кортежний.