关闭的局部变量与匿名操作中的预期不同

时间:2018-08-20 22:50:03

标签: c# .net

我目前在下面的代码中尝试调用匿名Action<>,并使用闭包捕获局部变量。

编辑:原始问题(简化但实用)

public class B
{
    void MyMethod(A instanceA)
    {
        var someRefType = new RefType();
        someRefType.DoSomething();
        someRefType.DoSomethingLater(a => instanceA.ModifyRefType(someRefType));
    }
}

public class A
{
    private Action<object> _action;

    public void ModifyRefType(Action<object> action)
    {
        this._action = action;
    }

    public void DoModify(object configuration)
    {
        this._action?.Invoke(configuration);
    }
}

据我所知,闭包应该捕获局部变量,以便对MyMethod()的每次调用都将在someRefType的不同实例上关闭。但是,当我多次调用MyMethod()并随后调用Action中提供的匿名DoSomethingLater()时,对ModifyRefType()的所有调用都使用相同的实例(在最后一次致电MyMethod())。

我在这里想念什么?并且关闭someRefType以便使每个动作都获得适当实例的最佳方法是什么?

编辑:正如@dasblinkenlight和@EricLippert怀疑的那样,这与关闭someRefType无关。问题正在解决(在这个可怕的示例中)this。我已经相应地更新了代码。

1 个答案:

答案 0 :(得分:0)

如上面的评论所述,最终这不是关闭范围问题。下面是一些带有“解决方案”的简化代码。

public class B
{
    void MyMethod()
    {
        var instanceA = new A();
        var someRefType = new RefType();
        someRefType.DoSomething();
        someRefType.DoSomethingLater(a => instanceA.ModifyRefType(someRefType));
    }
}

public class A
{
    private Action<object> _action;

    public void ModifyRefType(Action<object> action)
    {
        this._action = action;
    }

    public void DoModify(object configuration)
    {
        this._action?.Invoke(configuration);
    }
}

摘要:instanceA的每个调用都(偶然)使用了相同的instanceA.ModifyRefType(),这意味着操作使用的是相同的闭包,该闭包同时围绕someRefType和{{1 }}。

谢谢您的帮助!