user10184098
user10184098

Reputation:

Access scope variables from delegate

This will sound strange, but is it possible to access the properties of a class instance from the delegate implementation? I'd like to give the class user the ability to inject more code and functionality (executed during run-time) into the class. If the following approach is not possible, do I have any other options?

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();

Upvotes: 1

Views: 501

Answers (2)

Guy Dunski
Guy Dunski

Reputation: 11

Yes you can do that. the reference to the instance t exists in your scope thus you can refer to it in your inline method like this:

t.A = () => { t.P = 3; };
  • Please note the code example you uploaded won't compile. 'class' should be written with lower case first letter and you did not not declare the variable t type.

Upvotes: 1

haim770
haim770

Reputation: 49095

In C#, the this keyword is bound to the lexical scope, so it will always refer to the class instance where the Action is assigned.

To overcome this, you can simply pass the Test instance as a parameter to the Action as follows:

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

Usage:

var t = new Test();

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

t.Run();

Alternatively, you can "capture" your current reference to t using a closure, but that would usually require the compiler to generate a type to represent that delegate (which might have performance issues, depending on your scenario):

var t = new Test();

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

t.Run();

Upvotes: 2

Related Questions