Is there a reason for C#'s reuse of the variable in a foreach?

前端 未结 4 977
梦如初夏
梦如初夏 2020-11-21 22:27

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s          


        
4条回答
  •  不要未来只要你来
    2020-11-21 23:07

    In C# 5.0, this problem is fixed and you can close over loop variables and get the results you expect.

    The language specification says:

    8.8.4 The foreach statement

    (...)

    A foreach statement of the form

    foreach (V v in x) embedded-statement
    

    is then expanded to:

    {
      E e = ((C)(x)).GetEnumerator();
      try {
          while (e.MoveNext()) {
              V v = (V)(T)e.Current;
              embedded-statement
          }
      }
      finally {
          … // Dispose e
      }
    }
    

    (...)

    The placement of v inside the while loop is important for how it is captured by any anonymous function occurring in the embedded-statement. For example:

    int[] values = { 7, 9, 13 };
    Action f = null;
    foreach (var value in values)
    {
        if (f == null) f = () => Console.WriteLine("First value: " + value);
    }
    f();
    

    If v was declared outside of the while loop, it would be shared among all iterations, and its value after the for loop would be the final value, 13, which is what the invocation of f would print. Instead, because each iteration has its own variable v, the one captured by f in the first iteration will continue to hold the value 7, which is what will be printed. (Note: earlier versions of C# declared v outside of the while loop.)

提交回复
热议问题