Сохранить ссылку на тип значения?

Я пишу объект "Монитора" упростить отладку моего приложения. К этому объекту Монитора можно получить доступ во время выполнения от интерпретатора IronPython. Мой вопрос, действительно ли возможно в C# сохранить ссылку на тип значения? Скажите, что у меня есть следующий класс:

class Test
{
    public int a;
}

Я могу так или иначе сохранить "указатель" на "a", чтобы быть в состоянии проверить, что это - значение в любое время? Это - возможный использующий безопасный и управляемый код?

Спасибо.

38
задан Alex Turpin 13 February 2010 в 00:53
поделиться

2 ответа

Вы не можете сохранить ссылку на переменную в поле или массиве. CLR требует, чтобы ссылка на переменную была в (1) формальном параметре, (2) локальном или (3) возвращаемом типе метода. C # поддерживает (1), но не два других.

(В стороне: возможно , чтобы C # поддерживал два других; на самом деле я написал прототип компилятора, который реализует эти функции. Это довольно удобно. (См. http: // ericlippert.com/2011/06/23/ref-returns-and-ref-locals/ для подробностей. Конечно, нужно написать алгоритм, который проверяет, что ни один ref local не может ссылаться на локальный, который был на уже уничтоженном стековом фрейме, что становится немного сложно, но выполнимо. Возможно, мы поддержим это в гипотетической будущей версии языка. (ОБНОВЛЕНИЕ: это было добавлено в 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.

54
ответ дан 27 November 2019 в 03:41
поделиться

Нет - вы не можете хранить "указатель" на тип значения непосредственно в C#.

Обычно вы храните ссылку на экземпляр Test, содержащий "a" - это дает вам доступ к a (через testInstance.a).

9
ответ дан 27 November 2019 в 03:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: