Foreach Variable in Closure. Why Results Differ for These Snippets?

This question already has an answer here:

  • Access to foreach variable in closure warning 3 answers

  • Resharper gives this description: "Access to foreach variable in closure. May have different behaviour when compiled with different versions of compiler." Why may it have a different behaviour?

    There was a breaking change between C# 4 and C# 5 due to the way the loop variable in foreach was impacted by closures, notably since the introduction of lambda expressions in C# 3. Resharper is warning you of this, in case you might depend or otherwise have come to expect the former semantics.

    The quick upshot is that in C# 4, the loop variable was shared between each iteration of the loop, and closures capture the variable, so it led to unexpected results for most people when they closed over the loop variable.

    In C# 5, each iteration of the loop gets its own variable, so closures in one iteration do not close over the same variable as other iterations, leading to more expected outcomes (for most people).

    That gets us to the heart of your problem:

    In the first snippet all tasks start with their own message, while in the second one all tasks start with the same message?

    In your first snippet, you are creating a copy of the loop variable inside your loop and the closure is occuring over the inner variable. In the second, you close over the loop variable directly. Presumably, you are running under C# 4, so the former semantics apply. If running in C# 5, the loop outputs from both versions should be consistent. This is the change Resharper refers to, and it should also let you understand how to structure your code in C# 4 (namely, use the first version you have written).

    As Justin Pihony points out in the comments, Eric Lippert has written a very useful blog article on the former semantics that also alludes to the change for C# 5.


    Your second code sample has a single messageToSend , which all of the lambda expressions capture in their closures.

    When the delegates run, they use the current value of the variable.

    链接地址: http://www.djcxy.com/p/21328.html

    上一篇: C#编译器版本和语言版本之间的区别

    下一篇: 关闭时的Foreach变量。 为什么结果不同这些片段?