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

标签 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()多次然后调用匿名ActionDoSomethingLater() 中提供, 所有对 ModifyRefType() 的调用使用相同的实例(在最后一次调用 MyMethod() 时创建的实例)。

我在这里错过了什么?关闭 someRefType 的最佳方式是什么?这样每个 Action 都会得到正确的实例?

编辑:正如@dasblinkenlight 和@EricLippert 所怀疑的那样,这不是关闭someRefType 附近的问题。 .问题正在关闭(在这个可怕的例子中)this .我已经相应地更新了代码。

最佳答案

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

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() 的每次调用,这意味着该操作正在使用相同的闭包someRefTypeinstanceA

谢谢你的帮助!

关于c# - 关闭的局部变量与匿名操作中的预期不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51939463/

相关文章:

c# - .NET UserControl 接受按钮最佳实践?

c# - Task.Factory.StartNew 和同步上下文

c# - 多对多关系插入

c# - .Net 邮件重复

c# - 如何用另一个 DocumentText 更新 DocumentText

c# - 在不同文化中格式化数字

c# - 如何实现ASP.Net级联DropDownList控件?

c# - 配置为使用 Markdown 时,Orchard 中的语法高亮代码片段

c# - 在解决方案资源管理器中的文件下添加文件

mysql - 客户端的 WAMP MYSQL 或 MYSQL 服务?