Изменится ли исходный объект, если его переопределить внутри метода?

«Изменится ли исходный объект, если его переопределить внутри метода?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ответ зависит от того, что понимать под "переопределением". В C# аргументы по умолчанию передаются по значению, но для ссылочных типов передается копия ссылки на объект в куче.

1. Изменение состояния объекта (свойств/полей): Такие изменения сохранятся для исходного объекта, потому что и внешняя переменная, и параметр метода указывают на один и тот же объект в памяти.

2. Переназначение ссылки параметра ("переопределение"): Если внутри метода параметру присвоить новый объект (obj = new MyClass()), это не повлияет на исходную внешнюю переменную. Вы просто меняете, куда указывает локальная копия ссылки.

public class DemoObject
{
    public int Value { get; set; }
}

public void ModifyObject(DemoObject obj)
{
    // 1. Изменение состояния — РАБОТАЕТ
    obj.Value = 100; // Исходный объект изменится.

    // 2. Переназначение ссылки — НЕ РАБОТАЕТ для внешней переменной
    obj = new DemoObject { Value = 999 }; // Локальная ссылка теперь указывает на новый объект.
}

// Использование:
var myObj = new DemoObject { Value = 5 };
Console.WriteLine($"До: {myObj.Value}"); // До: 5

ModifyObject(myObj);

Console.WriteLine($"После: {myObj.Value}"); // После: 100 (не 999!)
// myObj по-прежнему ссылается на исходный объект со значением 100.

Как заставить метод изменить саму ссылку? Используйте ключевые слова ref или out. Они передают ссылку на переменную-указатель, позволяя изменить, на какой объект она ссылается.

public void ReplaceObject(ref DemoObject obj)
{
    obj = new DemoObject { Value = 999 }; // Теперь изменит исходную переменную.
}

ReplaceObject(ref myObj);
Console.WriteLine($"После ref: {myObj.Value}"); // После ref: 999

Вывод: Изменять состояние объекта внутри метода можно всегда. Чтобы заменить сам объект, на который ссылается внешняя переменная, требуется ref/out.