从委托访问范围变量

时间:2018-08-27 15:34:22

标签: c# delegates

这听起来很奇怪,但是可以从委托实现中访问类实例的属性吗?我想让类用户能够向类中注入更多的代码和功能(在运行时执行)。如果无法采用以下方法,我还有其他选择吗?

Test.cs:

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

主要:

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

是的,您可以这样做。对实例t的引用存在于您的范围内,因此您可以在内联方法中像这样引用它:

t.A = () => { t.P = 3; };
  • 请注意,您上载的代码示例将无法编译。 “类”应使用小写首字母书写,并且您未声明变量t类型。