【问题标题】:Access scope variables from delegate从委托访问范围变量
【发布时间】:2018-08-28 00:50:38
【问题描述】:

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

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

【问题讨论】:

  • 为什么不把它作为参数传递给委托?
  • 关闭应该管理这个。你试过了吗?你有遇到什么问题吗?
  • 类中有很多属性。
  • @Alex 你的代码可以工作(有一些小的语法更正),但正确的方法是 haim770 提出的方法
  • 也许我误解了这个问题,但t.A = () => { t.P = 100;}; 在你的主要工作中效果很好。

标签: c# delegates


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    t.A = () => { t.P = 3; };
    
    • 请注意,您上传的代码示例无法编译。 'class' 的首字母应该小写并且你没有声明变量 t 类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-16
      • 2013-06-12
      • 1970-01-01
      相关资源
      最近更新 更多