OOP Course
Сьогодні

Підрозділ 8.5

Змінні-посилання та повернення посилання

Розглядає ref local, повернення посилання з методу, зміну значення через посилання та обмеження для ref return.

8.5. Змінні-посилання та повернення посилання

Ми вже знаємо, що параметр із модифікатором ref дозволяє методу змінювати значення змінної, що знаходиться у викликаючому коді — бо передається не копія значення, а посилання на ділянку пам'яті. У C# ці можливості йдуть далі: можна визначити локальну змінну-посилання (ref local) і повертати посилання з методу (ref return). Це дозволяє маніпулювати значеннями в масивах і структурах безпосередньо в пам'яті, без копіювання.

Змінна-посилання (ref local)

Звичайне присвоєння double copy = x створює копію — нову ділянку пам'яті з тим самим значенням. Зміна copy не впливає на x. Якщо ж визначити змінну з ключовим словом ref, вона стане псевдонімом (alias) для вже існуючої ділянки пам'яті:

double pulse = 72.0;
ref double pulseRef = ref pulse; // pulseRef — псевдонім для pulse

Тепер pulseRef і pulse — це два імені для одного й того самого місця в пам'яті. Зміна одного одразу відображається в іншому.

ref-змінна: псевдонім vs копія

Ref-змінну обов'язково потрібно ініціалізувати при оголошенні — визначити, на що вона вказує. Просте оголошення без ініціалізації не скомпілюється:

ref double r; // помилка — ref local без ініціалізації

Побачимо поведінку на практиці:

Повернення посилання з методу (ref return)

Окрім локальних ref-змінних, C# дозволяє повернути посилання з методу. Це корисно, коли потрібно дати зовнішньому коду прямий доступ до елемента масиву або поля структури — без копіювання значення туди й назад.

Для цього в сигнатурі методу перед типом результату вказується ref, і після return також ставиться ref:

ref double Find(double target, double[] array)
{
    for (int i = 0; i < array.Length; i++)
        if (array[i] == target)
            return ref array[i]; // повертаємо посилання на елемент
    throw new IndexOutOfRangeException("значення не знайдено");
}

Та при виклику змінна, що приймає результат, теж визначається з ref:

ref double element = ref Find(target, array);
element = newValue; // змінює безпосередньо елемент масиву

Застосуємо це в клінічному сценарії — знайдемо конкретний показник пульсу в журналі вимірювань і замінимо його виправленим значенням:

Зверніть увагу: метод FindReading повертає не значення 120.0, а посилання на комірку пам'яті arr[2]. Тому присвоєння wrong = 78.0 змінює саме цю комірку — елемент оригінального масиву readings.

ref return для двох значень

Ще один практичний приклад — метод, що повертає посилання на більше з двох значень. Це дозволяє безпосередньо змінити максимальний показник:

Параметри методу MaxRef також визначені з ref — бо метод повертає посилання на один із них, а посилання повинно вказувати на змінну, що існує поза межами методу.

ref readonly: посилання тільки для читання

Якщо потрібно дати доступ до елемента за посиланням (без копіювання), але захистити його від зміни, використовується ref readonly:

ref readonly double element = ref array[i]; // не можна змінити через element
// element = 99.0; // помилка компіляції

Це зручно для read-only доступу до великих структур — ми уникаємо копіювання, але гарантуємо, що значення не зміниться через цю змінну.

Обмеження методів із ref return

Метод, що повертає посилання, підпорядковується певним правилам. Він не може повертати посилання на:

Що заборонено Причина
null Посилання повинно вказувати на реальну ділянку пам'яті
Константу або літерал Константи не мають адреси у купі
Значення enum Аналогічно
Властивість класу або структури Властивість не є змінною — це метод
Поле з модифікатором readonly Захищено від змін
Локальну змінну всередині методу Вона зникає після виходу з методу

Повертати можна лише посилання на елементи масивів, поля екземпляра (без readonly) або параметри ref/out, — тобто на те, що існує поза межами поточного стекового кадру.

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