Это связано с тем, что когда мы записываем переменную в объект ссылочного типа, существует вид двух частей: фактический экземпляр объекта и ссылка, которую представляет имя переменной (указатель адреса памяти 32-битный или 64-битный внутри, зависит от платформы). Вы можете ясно видеть это с помощью этого фрагмента sharplab.io .
Когда мы вызываем метод, этот указатель копируется, а экземпляр - нет, поэтому:
var a = new Blah {Prop = "1"}; // Blah is a class, a reference type
Method(a);
void Method(Blah blah)
{
blah.Prop = "2"; // changes the shared instance, we know this.
blah = new Blah {Prop = "3"}; // has no effect.
}
Console.WriteLine(a.Prop); // 2
Видите ли, когда мы устанавливаем blah
внутри метода, мы изменяем нашу локальную ссылку, а не общую. Теперь, если мы используем ключевое слово ref
:
var a = new Blah {Prop = "1"};
Method(ref a);
void Method(ref Blah blah)
{
blah.Prop = "2"; // changes the shared instance, we know this.
blah = new Blah {Prop = "3"}; // now changes ref a outside
}
Console.WriteLine(a.Prop); // 3!
, поскольку параметр blah
передается по ссылке, когда мы его мутируем, мы мутируем исходную ссылку a
.