C# 关闭的局部变量在匿名操作中不符合预期

C# 关闭的局部变量在匿名操作中不符合预期,c#,.net,C#,.net,我现在有下面的代码,我试图调用一个匿名的操作,闭包捕获一个局部变量 编辑:原始问题(简化但实用) 公共B类 { void MyMethod(一个实例) { var someRefType=new RefType(); someRefType.DoSomething(); someRefType.DoSomethingLater(a=>instanceA.ModifyRefType(someRefType)); } } 公共A类 { 私人行动; 公共void ModifyRefType(操作) {

我现在有下面的代码,我试图调用一个匿名的
操作
,闭包捕获一个局部变量

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

公共B类
{
void MyMethod(一个实例)
{
var someRefType=new RefType();
someRefType.DoSomething();
someRefType.DoSomethingLater(a=>instanceA.ModifyRefType(someRefType));
}
}
公共A类
{
私人行动;
公共void ModifyRefType(操作)
{
这个._action=action;
}
public void DoModify(对象配置)
{
此._操作?.Invoke(配置);
}
}
在我看来,闭包应该捕获局部变量,这样对
MyMethod()
的每次调用都会在
someRefType
的不同实例上关闭。但是,当我多次调用
MyMethod()
并随后调用
DoSomethingLater()
中提供的匿名
操作时,对
ModifyRefType()
的所有调用都使用相同的实例(上次调用
MyMethod()
时创建的实例)

我错过了什么?关闭someRefType
someRefType
的最佳方法是什么,以使每个操作都得到正确的实例


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

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

公共B类
{
void MyMethod()
{
var instanceA=newa();
var someRefType=new RefType();
someRefType.DoSomething();
someRefType.DoSomethingLater(a=>instanceA.ModifyRefType(someRefType));
}
}
公共A类
{
私人行动;
公共void ModifyRefType(操作)
{
这个._action=action;
}
public void DoModify(对象配置)
{
此._操作?.Invoke(配置);
}
}
摘要:每次调用
instanceA.ModifyRefType()
时(意外地)都会使用相同的
instanceA
,这意味着操作使用的闭包与
someRefType
instanceA
的闭包相同


谢谢你的帮助

请提供一个最小的可验证的自包含示例。使用您提供的伪方法无法回答此问题。请阅读@EricLippert的博客,了解为什么闭包的初始实现与循环变量的当前作用域冲突:。正如dasblinkenlight所说,如果没有一个复制这个问题的小程序,就不可能说出这里发生了什么。您对by design闭包语义的描述是正确的,因此要么您的程序没有执行您所说的操作,要么编译器有错误。如果你的程序没有做到你所说的,我们就无法告诉你,没有这个程序,你的思维过程哪里出了问题。如果编译器有bug,编译器团队将需要重新编译。不管怎样,没有复制机我们都帮不了你。我还注意到你正在接近
someRefType
this
。你确定你没有看到
这个
在每个闭包中被重复使用,也没有
someRefType
?我为模糊的代码片段道歉-我原以为这是对闭包的错误理解,而不是一个单独的问题。我将用更好的代码示例更新这个问题。谢谢
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);
    }
}
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);
    }
}