Доступ к переменным области видимости от делегата - PullRequest
0 голосов
/ 27 августа 2018

Это будет звучать странно, но возможно ли получить доступ к свойствам экземпляра класса из реализации делегата? Я хотел бы дать пользователю класса возможность вводить больше кода и функциональности (выполняемой во время выполнения) в класс. Если следующий подход невозможен, есть ли у меня другие варианты?

Test.cs:

Class Test{
  public int P {get; set;}; 
  public Action A; 
  public void Run(){ 
    this.A(); 
 }
}

Main:

t = new Test(); 
t.A = () => { /* Modify t.P in here. */}; 
t.Run();

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Да, вы можете сделать это. ссылка на экземпляр t существует в вашей области видимости, поэтому вы можете ссылаться на нее во встроенном методе следующим образом:

t.A = () => { t.P = 3; };
  • Обратите внимание, что загруженный вами пример кода не будет компилироваться. 'class' должен быть написан с первой строчной буквы, и вы не объявляли тип переменной t.
0 голосов
/ 27 августа 2018

В C # ключевое слово this связано с лексической областью, поэтому оно всегда будет ссылаться на экземпляр класса, которому назначен Action.

Чтобы преодолеть это, вы можете просто передать экземпляр Test в качестве параметра Action следующим образом:

public class Test
{
    public int P { get; set; }
    public Action<Test> A;
    public void Run()
    {
        this.A(this);
    }
}

Использование:

var t = new Test();

t.A = test =>
{
    // you can now access `Test` properties
    var p = test.P;
};

t.Run();

В качестве альтернативы, вы можете «захватить» вашу текущую ссылку на t, используя замыкание, но для этого обычно требуется, чтобы компилятор генерировал тип для представления этого делегата (что может иметь проблемы с производительностью, в зависимости от вашего сценария):

var t = new Test();

t.A = () => {
    // access Test properties using `t`
    var p = t.P;
};

t.Run();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...