Нельзя хранить ссылку на переменную в поле или массиве. CLR требует, чтобы ссылка на переменную была в (1) формальном параметре, (2) локальном или (3) возвращаемом типе метода. C # поддерживает (1), но не два других.
(ВНИМАНИЕ: возможно для C # для поддержки двух других; на самом деле я написал прототип компилятора, который реализует эти функции. Он довольно изящен. детали.) Конечно, нужно написать алгоритм, который проверяет, что никакая ссылка локальная не может ссылаться на локальную, которая была в разрушенном кадре стека, что немного сложно, но выполнимо. Возможно, мы поддержим это гипотетическая будущая версия языка. (ОБНОВЛЕНИЕ: оно было добавлено в C # 7!))
Однако вы можете сделать так, чтобы переменная имела произвольно большое время жизни, поместив ее в поле или массив. Если вам нужна «ссылка» в смысле «мне нужно сохранить псевдоним для произвольной переменной», то нет. Но если вам нужна ссылка в смысле «мне нужен магический токен, который позволяет мне читать и записывать определенную переменную», тогда просто используйте делегат или пару делегатов.
sealed class Ref<T>
{
private Func<T> getter;
private Action<T> setter;
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value
{
get { return getter(); }
set { setter(value); }
}
}
...
Ref<string> M()
{
string x = "hello";
Ref<string> rx = new Ref<string>(()=>x, v=>{x=v;});
rx.Value = "goodbye";
Console.WriteLine(x); // goodbye
return rx;
}
Внешняя локальная переменная x останется в живых, по крайней мере, до восстановления rx.