OOP Course
Сьогодні

Підрозділ 8.6

Методи розширення

Показує методи розширення, їх синтаксис через this у першому параметрі та правила дії в межах простору імен.

8.6. Методи розширення

Уявіть ситуацію: вам потрібно додати корисний метод до класу string або структури DateTime — але ви не маєте доступу до їх вихідного коду і не можете успадкуватися від них (string — sealed-клас, а від структур успадковуватися неможливо взагалі). Або ви хочете додати утиліти до типів зі сторонньої бібліотеки, не чіпаючи її код. Саме для цього існують методи розширення (extension methods) — механізм, який дозволяє «додавати» нові методи до будь-якого типу ззовні, без зміни його вихідного коду.

Методи розширення — це не магія. За лаштунками вони залишаються звичайними статичними методами. Але компілятор дозволяє викликати їх через крапку, як ніби вони є рідними методами типу:

double temp = 38.5;
bool hasFever = temp.IsFever(); // виглядає як метод double
// компілятор транслює це в:
bool hasFever = TemperatureExtensions.IsFever(temp);

Це синтаксичний цукор — зручний запис, що приховує звичайний статичний виклик.

Синтаксис методу розширення

Метод розширення визначається у public static класі як public static метод. Перший параметр — особливий: він позначається ключовим словом this і вказує, який тип цей метод розширює. При виклику цей параметр не передається явно — компілятор підставляє значення зліва від крапки.

Методи розширення: синтаксис і механізм компіляціїМетоди розширення: синтаксис і механізм компіляції

public static class TemperatureExtensions
{
    public static bool IsFever(this double celsius) => celsius > 37.5;
    //                         ^^^^ — розширюємо тип double
}

Розширення вбудованих типів: double

Додамо кілька корисних методів до double для роботи з температурними показниками — типовий сценарій у клінічних системах:

Розширення вбудованих типів: string

Методи розширення особливо корисні для string — дозволяють додавати специфічну бізнес-логіку без успадкування. Додамо методи для роботи з медичними рядками:

Розширення DateTime

Методи розширення для DateTime зручні для бізнес-логіки, яка не належить до самого класу DateTime, але часто потрібна в конкретному домені:

Правила та обмеження

Простір імен. Методи розширення діють у межах простору імен (namespace). Якщо статичний клас із методами розширення знаходиться в іншому namespace, його потрібно підключити через using:

using ClinicApp.Extensions; // підключаємо простір імен зі статик-класом

string code = "ICD-10";
bool valid = code.IsValidMedicalCode(); // тепер доступний

Пріоритет instance-методу. Якщо тип вже має метод із тією самою сигнатурою, що й метод розширення, буде викликаний рідний метод — метод розширення ігнорується. Ця поведінка захищає від випадкового перевизначення поведінки існуючого типу.

Де доцільно використовувати extension methods:

  • Додавання утилітарних методів до типів, яких ми не контролюємо (string, DateTime, типи з бібліотек).
  • Розширення sealed-класів, від яких не можна успадкуватися.
  • Організація допоміжної логіки окремо від основного класу (принцип єдиної відповідальності).
  • Побудова fluent API: patient.GetAge().IsAdult().HasInsurance().

Варто знати: весь механізм LINQ (Where, Select, OrderBy, GroupBy тощо) реалізований саме через методи розширення для IEnumerable<T>. Коли ви пишете list.Where(p => p.Age > 18), ви викликаєте статичний метод Enumerable.Where(list, p => p.Age > 18) — і це саме метод розширення.

Члени розширення в C# 14

Класичний синтаксис дозволяє додати до типу лише методи. C# 14 (.NET 10) вводить блоки розширення (extension), у яких можна оголошувати також властивості і статичні члени розширеного типу:

public static class TemperatureExtensions
{
    extension(double celsius)            // «приймач» — як this-параметр
    {
        public bool IsFever() => celsius >= 37.5;            // метод
        public bool IsNormalRange => celsius is >= 36.0 and <= 37.0; // властивість!
    }
}

// Використання:
double t = 36.6;
bool fever  = t.IsFever();   // false
bool normal = t.IsNormalRange;   // true — властивість без дужок

Для коду, що викликає, нічого не змінюється: це ті самі статичні члени статичного класу, а класичні методи з this і нові блоки сумісні між собою. Перевірено на .NET 10.

Одна пастка, знайдена під час перевірки: властивість спершу хотілося назвати IsNormal, але в double вже є статичний метод double.IsNormal(double). Правило пріоритету діє й тут — член самого типу перемагає розширення, тому t.IsNormal компілятор прив'язує до групи методів double.IsNormal, і рядок не компілюється (CS1503). Звідси ім'я IsNormalRange.

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