Підрозділ 9.Q
Питання для самоконтролю
Питання для самоконтролю — Розділ 9. Pattern matching 9.1. Патерн типів 1. Що таке pattern matching у C і яку проблему він вирішує порівняно зі старим підходом через is + явний cast? 2. Що виведе наступний код
Питання для самоконтролю — Розділ 9. Pattern matching
9.1. Патерн типів
Що таке pattern matching у C# і яку проблему він вирішує порівняно зі старим підходом через
is+ явний cast?Що виведе наступний код і чому?
object value = "Гіпертонія"; if (value is string s) Console.WriteLine(s.ToUpper()); else Console.WriteLine("не рядок"); Console.WriteLine(s); // чи компілюється цей рядок?Поясніть, у чому різниця між трьома формами:
// Форма A if (staff is Doctor) { Doctor doc = (Doctor)staff; doc.PrescribeMeds(); } // Форма B Doctor? doc = staff as Doctor; if (doc != null) doc.PrescribeMeds(); // Форма C if (staff is Doctor doc) doc.PrescribeMeds();Яка форма є найкращою і чому?
Поясніть різницю між switch statement і switch expression. Коли варто обирати кожен варіант? Який з них повертає значення?
Чому в
switchконкретніші типи мають іти перед базовими? Що станеться, якщо розміститиMedicalStaffпередDoctor? Чи попередить компілятор про помилку?Напишіть метод
Describe(object obj), який через switch expression повертає рядок опису для:int(значення числа),string(значення рядка),null(рядок "null"), будь-якого іншого типу (назва типу черезGetType().Name).Що таке constant pattern і де він використовується? Поясніть, чим
is not nullвідрізняється від!= nullз точки зору компілятора.Порівняйте switch expression з type pattern і класичний ланцюг
if-else + castза такими критеріями: кількість операцій для перевірки типу, ризикInvalidCastException, можливість повертати значення, підтримка нових типів у ієрархії.
9.2. Патерн властивостей
Що таке патерн властивостей і чим він доповнює патерн типів? Запишіть синтаксис у двох формах: без перевірки типу і з перевіркою типу одночасно.
Що виведе наступний код?
var p = new Patient("Коваль", "Active", priority: 2); string result = p switch { { Status: "Active", Priority: > 3 } => "Терміново", { Status: "Active", Priority: > 1 } => "Плановий", { Status: "Active" } => "Рутинний", _ => "Інше", }; Console.WriteLine(result);Навіщо в патерні властивостей використовується
var ім'язамість конкретного значення? Наведіть приклад, коли це зручно.Поясніть різницю між синтаксисом вкладених об'єктів до C# 10 і після C# 10:
// До C# 10 if (patient is { Department: { Name: "Кардіологія" } }) // C# 10+ if (patient is { Department.Name: "Кардіологія" })Чи є між ними функціональна різниця?
Що означає патерн
{}(порожні фігурні дужки) у switch expression? Чим він відрізняється від_?Спроєктуйте switch expression для класу
MedicalStaffз підкласамиDoctorіNurse, де для лікаря потрібно перевірятиIsOnLeaveіSpecialty, а для медсестри —Ward. Поєднайте type pattern та property pattern.Чому вираз
Priority: > 3у патерні властивостей є поєднанням двох різних видів патернів? Поясніть, як вони вкладаються.Знайдіть помилку у наступному коді і поясніть, як її виправити:
string GetStatus(Patient? p) => p switch { { Status: "Active" } => "Активний", {} => "Неактивний", null => "Null" };
9.3. Патерни кортежів
Що таке кортежний патерн і коли його слід обирати замість патерну властивостей або патерну типів? Наведіть відмінну рису сценарію застосування.
Що виведе наступний код?
string result = ("Хірургія", "Ніч") switch { ("Кардіологія", "День") => "Плановий", ("Хірургія", "День") => "Операційний зал", ("Хірургія", _) => "Ургентна хірургія", (_, "День") => "Денний прийом", _ => "Позаплановий", }; Console.WriteLine(result);Поясніть роль
discard(_) в кортежному патерні. Чим він відрізняється відvar?Чому порядок arm-ів у кортежному switch має принципове значення? Що станеться, якщо arm з
_розмістити першим?Напишіть функцію
string GetRiskLevel(int systolic, int age), яка за допомогою кортежного патерну визначає рівень ризику: критичний (тиск >= 180), підвищений + похилий вік (>= 140, >= 60), підвищений молодший, норма.Що означає поява
>= 60 and < 120в позиції кортежного патерну? Які ще патерни можна вставляти в позиції кортежу?Що відбувається у runtime, якщо жоден arm у switch expression не збігається і відсутній
_? Як цього уникнути?Порівняйте кортежний патерн і вкладені
if-elseдля логіки, яка залежить від двох незалежних вхідних значень. Які переваги і недоліки кожного підходу?
9.4. Позиційний патерн
Що таке позиційний патерн і в чому його відмінність від кортежного патерну? Яка технічна вимога до класу, щоб він підтримував позиційний патерн?
Поясніть три кроки, які виконує компілятор при зіставленні об'єкта з позиційним патерном
(pat1, pat2).Чому позиційний
recordавтоматично підтримує позиційний патерн без додаткового коду? Що генерує компілятор дляrecord VitalSigns(double Temperature, int Pulse)?Що виведе наступний код?
public record VitalSigns(double Temperature, int Pulse, int OxygenSat); var v = new VitalSigns(38.8, 105, 96); string result = v switch { (>= 39.0, > 90, _) => "КРИТИЧНО", (>= 38.5, _, _) => "Жар", (_, _, < 90) => "Гіпоксія", (var t, var p, var o2) => $"Стан: {t} {p} {o2}", }; Console.WriteLine(result);Клас
Appointmentмістить три поля:PatientName,Type,Department. УDeconstructрозкрито лишеTypeіDepartment. Чому неPatientName? Як тоді отриматиPatientNameпри зіставленні?Напишіть клас
BloodPressureз полямиSystolicіDiastolic, додайтеDeconstruct, і реалізуйте методstring Assess(BloodPressure bp)через позиційний патерн.Порівняйте кортежний та позиційний патерни за такими критеріями: тип вхідних даних, вимоги до класу, типовий сценарій використання.
Чи можна поєднати позиційний патерн з патерном властивостей в одному arm? Якщо так — наведіть приклад; якщо ні — поясніть чому.
9.5. Реляційний та логічний патерни
Що таке реляційний патерн і чим він відрізняється від звичайного оператора порівняння
>? У яких місцях коду може стояти реляційний патерн?Поясніть принципову різницю між
&&таandу наступних фрагментах:if (temp > 37.5 && temp < 39.0) { ... } // A if (temp is > 37.5 and < 39.0) { ... } // BЧи однаковий результат? Чи однакова природа операторів?
Що виведе наступний код?
double[] temps = { 34.5, 36.6, 37.8, 39.2 }; foreach (var t in temps) { string r = t switch { < 35.0 => "Гіпотермія", >= 35.0 and < 36.0 => "Нижче норми", >= 36.0 and <= 37.0 => "Норма", > 37.0 and < 38.5 => "Субфебрильна", _ => "Жар або вище", }; Console.WriteLine($"{t}: {r}"); }Яка різниця між
not nullяк патерном і!= nullяк умовою? Як компілятор трактуєis not null?Поясніть пріоритет операторів
andтаorу патернах. Що означає виразtemperature is < 35 or > 39? Чи потрібні дужки для явного групування?Напишіть метод
string AssessPulse(int pulse), який через логічний патерн визначає: брадикардія (< 60), тахікардія (> 100), норма (60–100), критична тахікардія (> 150).Покажіть три місця, де можна використовувати реляційний патерн: після
is, в позиції кортежного патерну, в патерні властивостей. Наведіть конкретні приклади коду.Чому
not Doctorу контекстіstaff is not Doctorє патерним оператором, а не логічним запереченням? Що саме заперечуєnotу цьому виразі?
9.6. Патерни списків
Що таке патерн списків (list patterns)? В якій версії C# вони з'явились і які типи підтримують цей патерн?
Чому
IEnumerable<T>безCount/Lengthне підтримується патерном списків? Що генерує компілятор для перевірки[a, b, c]?Що виведе наступний код?
int[] data = { 130, 120, 95, 72 }; string result = data switch { [] => "Порожній", [var single] => $"Одне: {single}", [> 100, .., > 100] => "Стійка тахікардія", [var f, .., var l] when f > l + 20 => $"Спадання: {f}→{l}", [var f, .., var l] => $"Стан: {f}..{l}", }; Console.WriteLine(result);Поясніть синтаксис
..(slice) у патерні списків. Скільки разів він може з'являтися в одному патерні і чому?Що означає патерн
[var first, .., var last]? Що буде, якщо масив містить рівно 2 елементи? Що якщо 1 елемент?Напишіть метод
string ParseCommand(string[] args), який через патерн списків обробляє команди:["add", var name]→ додати,["remove", var id]→ видалити,["list"]→ список,[]→ порожня команда,_→ невідома команда.Як поєднати патерн списків з патерном властивостей в одній умові? Наведіть приклад з
and.Для яких практичних задач патерн списків є особливо виразним інструментом? Назвіть принаймні три сценарії. Чому він непридатний для
IEnumerable<T>з великою кількістю елементів?