最近我深入阅读了 C#,它教会了我有关 lambda 表达式的知识,我一直在使用它们将数据传递给单击事件等:
image.MouseDown+=(o ,e)=>MethodToDoSomething(DataNeededForAction);
现在这些问题是在 foreach 循环中使用时捕获变量(感谢 Jon Skeet 使这部分非常清楚:),当初始化几个具有我订阅的事件的对象时,我通常会遇到变量问题捕获。考虑以下示例:
foreach (var game in GamesCollection)
{
Image img = new Image();
img.Width = 100;
img.MouseDown+=(o,e) => MyMethod(game.id);
}
为了避免在这种情况下捕获,我必须添加一些变量来分配游戏,然后将该变量传递给方法,这会产生额外的不清晰代码,并且主要是额外的困惑。 有没有办法绕过这个?至少看起来更干净的东西?
谢谢,Ziv
最佳答案
(编辑:请注意,这已随 C# 5 发生变化,其中 foreach
现在有效地为每次迭代创建一个新变量。)
不,没有办法避免这种情况。基本上,语言规范根据单个变量而不是每次迭代一个新变量来描述 foreach
的方式是错误的。就所涉及的代码量而言,我个人认为这不是问题 - 当您意识到这是一个问题并想出解决方法时,您已经克服了最大的障碍。请注意,我通常会包含一条注释,让维护程序员一目了然。
我敢肯定,如果 C# 团队从头开始,他们的做法会有所不同,但事实并非如此。见鬼,they've even discussed changing the existing behaviour ...但是有充分的理由反对改变(特别是在 C# N+1 编译器上正确工作的代码仍然可以编译,但在 C# N 编译器上给出错误的结果;一个非常微妙的开源库作者希望他们的代码使用多个编译器构建的错误来源)。
(希望你喜欢这本书,顺便说一句......)
关于c# - 如何避免在 lambda 表达式中捕获变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5573838/