Позвольте мне перефразировать этот вопрос:
Могу ли я передать ссылку на переменную в качестве параметра в метод, который хранит ссылку, чтобы мой код мог позже обновить переменную?
Нет.
В системе типов CLR ссылки на переменные могут быть переданы как формальные параметры . Они также могут быть возвращены из вызовов методов и , хранящихся в локальных переменных, которые, как известно, имеют короткое время жизни . (C # не поддерживает последние две функции; подробности см. В моей статье на эту тему: http://blogs.msdn.com/b/ericlippert/archive/2011/06/23/ref-returns-and-ref-locals.aspx.)
Однако их нельзя хранить в полях или массивах. Вкратце, ссылки на переменные могут храниться только в местах, которые, как известно, недолговечны.
Причина этого ограничения в том, что вы не можете иметь все четыре из этих желательных качеств одновременно :
- Любая переменная может быть передана по ссылке
- Всегда безопасно получить доступ к ссылке на переменную (в безопасном коде; если переменная является разыменованием указателя из небезопасного кода, тогда вы несете ответственность за обеспечение ее безопасности, а не за время выполнения.)
- Переменные с коротким сроком службы можно очистить без сбора мусора (т. Е. Путем «извлечения стека» или повторного использования регистров или любой другой системы восстановления памяти, не основанной на gc, используемой для пула краткосрочного хранения. )
- Переменные ссылки могут храниться в местах долгосрочного хранения
Один из них должен дать, и дизайнеры CLR выбрали последний, который проиграл. Дизайнеры C и C ++ выбрали в качестве второго проигравшего.
Полагаю, это можно сделать с помощью отражения.
Не может. Но это можно сделать с делегатами.
class C
{
private Action<int> setter;
public void RecordSetter(Action<int> setter)
{
this.setter = setter;
}
public void SetIt(int x)
{
this.setter(x);
}
}
и теперь вы можете сказать:
class D
{
int myField;
void M()
{
C c = new C();
c.RecordSetter(x=>{myField = x; });
c.SetIt(123);
Console.WriteLine(myField);
}
}
Сборщик мусора обеспечит, чтобы экземпляр D оставался в живых до тех пор, пока экземпляр C остается живым.