如何升级到 C# 5.0?访问修改后的闭包
Posted
技术标签:
【中文标题】如何升级到 C# 5.0?访问修改后的闭包【英文标题】:how to upgrade to C# 5.0? access to modified closure 【发布时间】:2014-11-19 21:07:47 【问题描述】:我觉得问这个有点傻。请不要打我太重。
最近我一直在使用 .Net framework 4.5 和 Visual C# 2012 以及 C# 5.0 之前的编译器;和 Visual Studio 2012。
我开始使用 Tasks,对来自 Resharper 的“访问修改后的关闭”通知感到恼火。然后我读到,如果我升级到 .Net 框架 4.5.2 并升级到后 C# 5.0,它会“修复”for
和 foreach
,这样我就不必在 curly 中创建临时变量由于共享上下文,循环的括号。
所以我觉得很好,这将是一个简单的修复。我做了以下事情:
1) 检查我使用的是 Visual Studio 2012,并且它与新的 4.5.2 框架和 C# 5.0 (here) 兼容
2) 然后我下载并安装了开发者版本的 .Net 4.5.2 (here)
3) 然后,我将解决方案中的每个项目定位为使用 .Net 4.5.2 而不是 .Net 4.5。我重建,运行了我的单元测试,并获得了所有的绿灯。
4) 然后我转到任务代码,并尝试删除临时变量。瞧,它仍然警告我访问修改后的闭包;例如:
int numTasks = 1000;
var tasks = new Task<int>[numTasks];
for (int i = 0; i < numTasks; i++)
tasks[i] = Task.Delay(1).ContinueWith(a => i); // <-- warning
上面的代码,因为共享上下文,会产生错误的输出。对于 .Net 4.5 和 C# 5.0 之前的版本,解决此问题的方法是引入一个临时变量,如下所示:
int numTasks = 1000;
var tasks = new Task<int>[numTasks];
for (int i = 0; i < numTasks; i++)
int i1 = i;
tasks[i] = Task.Delay(1).ContinueWith(a => i1); <-- no warning, works great
我当然不喜欢这个,因为它很丑,必须评论让我的同事理解。我更愿意使用新版本的 C# 和 .Net 框架。
接下来我想,“如何检查我是否安装了 Visual Studio 2012 并使用了 C# 5.0?”这就是我卡住的地方。我的 Visual Studio 2012 环境似乎仍在使用 C# 4.5。我证明了这一点,即在执行我上面列出的升级步骤后,访问修改后的关闭问题没有解决。
有人可以帮助我了解如何摆脱 ****access to modified closure**** 问题,希望通过升级到 C# 5.0(如果这确实是我的问题)。
谢谢
【问题讨论】:
我远不是这方面的专家,但我认为这是与编译器/Visual Studio 相关的变化。你可能不是你可以随便加入的东西,你必须使用 VS 2013 嗯,如果正确的代码让他们感到不安,你需要新的同事。 C# v5 仅针对 foreach 修复它,而不针对 for。 【参考方案1】:警告是完全正确的。您正在关闭稍后修改的变量。您提供的示例代码在 C# 4.0 和 C# 5.0(或 C# 3.0 或 C# 6.0)中的行为没有什么不同。
在 C# 5.0 中只有 foreach
循环被更改,以便在每次迭代时重新创建循环变量。 for
循环没有改变,闭包的语义也没有改变。
【讨论】:
Eric Lippert 有一篇很棒的博文,名为 Closing over the loop variable considered harmful。 当然...我应该更仔细地阅读。感谢大家的快速解答。以上是关于如何升级到 C# 5.0?访问修改后的闭包的主要内容,如果未能解决你的问题,请参考以下文章
Do.. While.. 使用 Exists 谓词。访问修改后的闭包?