Ответ 1
Если я правильно понимаю, переменные, определенные в методе, хранятся в стеке и не зависят от сбора мусора.
Это зависит от того, что вы подразумеваете под "затронутым". Переменные в стеке являются корнями сборщика мусора, поэтому они, безусловно, влияют на сбор мусора.
Так как местоположение t находится в стеке, тогда эта память не может быть собрана или уплотнена мусором, а ссылочная переменная в Increment() всегда укажет на правильное содержимое t.
"Невозможно" - это странное слово для использования здесь. Точка использования стека в первую очередь заключается в том, что стек используется только для данных, которые никогда не нужно уплотнять и срок службы которых всегда известен, поэтому никогда не нужно собирать мусор. Вот почему мы используем стек в первую очередь. Кажется, вы ставите телегу перед лошадью. Позвольте мне повторить это, чтобы убедиться, что это понятно: причина, по которой мы храним этот материал в стеке, состоит в том, что его не нужно собирать или уплотнять, потому что его жизнь известна. Если бы его жизнь не была известна, то она пошла бы на кучу. Например, локальные переменные в блоках итератора идут по куче по этой причине.
Теперь t сохраняется в куче, поскольку это значение конкретного экземпляра моего класса.
Правильно.
Разве это не проблема, если передать это значение в качестве эталонного параметра?
Неа. Это прекрасно.
Если я передать т в качестве опорного параметра, р будет указывать на текущее местоположение т.
Угу. Хотя я предпочитаю думать, что p является псевдонимом для переменной t.
Однако, если сборщик мусора перемещает этот объект во время компактности, разве это не испортит ссылку на t в Increment()?
Неа. Сборщик мусора знает об управляемых ссылках; поэтому их называют управляемыми ссылками. Если gc перемещает объект, управляемая ссылка остается в силе.
Если вы указали фактический указатель на t, используя небезопасный код, вам потребуется привязать контейнер t к месту, чтобы сборщик мусора знал, что он не перемещает его. Вы можете сделать это, используя фиксированный оператор в С#, или создав GCHandle для объекта, который вы хотите вывести.
обновляет ли сборщик мусора даже ссылки, созданные путем передачи ссылочных параметров?
Угу. Это было бы довольно хрупким, если бы не было.
Нужно ли вообще об этом беспокоиться?
Неа. Вы думаете об этом как о неуправляемом программисте на С++ - С++ заставляет вас выполнять эту работу, но С# этого не делает. Помните, что весь смысл модели управляемой памяти - освободить вас от необходимости думать об этом.
Конечно, если вам нравится беспокоиться об этом, вы всегда можете использовать "небезопасную" функцию, чтобы отключить эти системы безопасности, а затем вы можете писать кучи и стеки, искажая ошибки в вашем сердечном содержимом.