Как влияет присваивание нового объекта внутри метода на внешний объект при передаче по ссылке в C#
Что проверяют
Понимаете ли вы, что в C# по умолчанию всё передаётся по значению, а у ссылочного типа значением является сама ссылка. Задача почти всегда идёт с кодом: что выведет программа после вызова метода. Следом спрашивают, что изменится с модификатором ref и как ведёт себя struct.
Как отвечать
Разведите два понятия: ссылочный тип и передача по ссылке. Это разные вещи.
- без модификатора: метод получает копию ссылки. Изменение поля через неё (
obj.Value = 20) видно снаружи, потому что обе ссылки указывают на один объект в куче. Присваиваниеobj = new MyClass(30)меняет только локальную копию, внешняя переменная по-прежнему указывает на старый объект; ref: метод получает саму переменную вызывающего. Теперьobj = new MyClass(30)заменит объект и снаружи, как иobj = null;out: тоже передача по ссылке, но метод обязан присвоить значение, а читать параметр до присваивания нельзя;inиref readonly: передача по ссылке без права менять переменную, полезно для больших структур, чтобы не копировать их;structбез модификатора: копируется целиком, поэтому изменение поля внутри метода снаружи не видно.
Отдельно упомяните string: он ссылочный, но неизменяемый. s += "!" внутри метода создаёт новую строку и снаружи ничего не меняет.
Хороший ответ заканчивается правилом: ref для ссылочного типа нужен только тогда, когда метод должен заменить сам объект у вызывающего. В остальных случаях чище вернуть новый объект результатом метода.
Где спотыкаются
Говорят «в C# объекты передаются по ссылке». Это путает ссылочные типы с передачей по ссылке, и интервьюер тут же даст задачу с присваиванием, на которой такое объяснение ломается.
Считают, что obj = null внутри метода обнулит внешнюю переменную. Без ref обнуляется только копия.
Путают поведение struct и class: ожидают, что изменение поля структуры внутри метода сохранится, как у класса.