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()
时创建的实例)
我错过了什么?关闭someRefTypesomeRefType
的最佳方法是什么,以使每个操作都得到正确的实例
编辑:正如@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);
}
}