В чем разница между параметрами ref и out в C#
Что проверяют
Знаете ли вы разницу в требованиях к инициализации и понимаете ли, что оба передают ссылку на переменную.
Как отвечать
Оба модификатора передают не значение, а ссылку на переменную вызывающего, поэтому метод может изменить саму переменную, а не копию. Разница в правилах инициализации:
- ref: переменная должна быть инициализирована до вызова. Метод может её прочитать и изменить;
- out: инициализация до вызова не нужна, но метод обязан присвоить значение до выхода. Читать входное значение он не может.
int a = 5;
Increment(ref a); // a обязано быть задано заранее
if (int.TryParse(s, out int n)) { ... } // n объявляется прямо в вызовеСмысл разный: ref это «дай мне доступ к твоей переменной», out это «верни мне ещё одно значение».
Классическое применение out это шаблон TryParse и TryGetValue: метод возвращает признак успеха, а сам результат отдаёт через параметр, избегая исключений на ожидаемых ошибках.
Что стоит добавить: оба нельзя использовать в асинхронных методах и в итераторах; для нескольких возвращаемых значений сегодня чаще берут кортеж, потому что читается лучше; есть ещё in для передачи большой структуры по ссибке только для чтения без копирования.
Где спотыкаются
Считают, что ref копирует значение, а out нет.
Забывают присвоить значение параметру out на всех путях выхода.
Используют out там, где уместнее вернуть кортеж или объект результата.
Пытаются применить их в async методе.