C# foreach循环中的匿名委托

C# foreach循环中的匿名委托,c#,delegates,foreach,scope,anonymous-function,C#,Delegates,Foreach,Scope,Anonymous Function,可能重复: 我想知道这里发生了什么现象: 将列表转换为返回相同字符串的代理列表会出错 当我直接使用输入列表上的foreach返回的变量时,erroconversion会发生这种情况。(每次都返回列表中的最后一个字符串) 在CorrectConversion中,我首先分配一个局部变量,并在委托中使用它 这项任务起初似乎是多余的 输入: using System.Collections.Generic; class Program { delegate string StringReturne

可能重复:

我想知道这里发生了什么现象:

列表
转换为返回相同字符串的代理列表会出错

当我直接使用输入列表上的
foreach
返回的变量时,
erroconversion
会发生这种情况。(每次都返回列表中的最后一个字符串)

CorrectConversion
中,我首先分配一个局部变量,并在委托中使用它

这项任务起初似乎是多余的

输入:

using System.Collections.Generic;
class Program
{
  delegate string StringReturner();

  static void Main(string[] args)
  {
    var list = new List<string> { "a", "b", "c" };
    Display(WrongConversion(list));
    Display(CorrectConversion(list));
    System.Console.ReadKey();
  }
  static List<StringReturner> WrongConversion(List<string> list)
  {
    var result = new List<StringReturner>();
    foreach (var s in list)
    {
      result.Add(() => { return s; });  // <========= s is always "c" ?
    }
    return result;
  }
  static List<StringReturner> CorrectConversion(List<string> list)
  {
    var result = new List<StringReturner>();
    foreach (var s in list)
    {
      var localString = s;              // <========= What happens here?
      result.Add(() => { return localString; });
    }
    return result;
  }
  private static void Display(List<StringReturner> list)
  {
    foreach (var stringReturner in list)
      System.Console.Write(stringReturner());
    System.Console.WriteLine();
  }
}
这是C#(我想也是VB.NET)中一个已知的“bug”。简单的答案是,您创建的localString变量的作用域在foreach中,因此每个iteration都会使用它的一个新副本,但是在另一种情况下,您只需引用s,最终会变成c(至少在打印它之前)。为了“解决”这类问题,我已将其作为一种实践

foreach(var _s = ....) {
    var s = _s;
    /* code here that uses s */
}

每次我都会使用这样的代表。

这是一百万个问题的重复。这与关闭局部变量有关。这也是StackOverflow社区已知的问题。因此,接近重复。
foreach(var _s = ....) {
    var s = _s;
    /* code here that uses s */
}