3

可能重复:
关于 foreach 和 delegates 的问题

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

将 aList<string>转换为返回相同字符串的委托列表会出错。

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

在 中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();
  }
}

输出:

ccc
abc
4

1 回答 1

-2

这是 C# 中的一个已知“错误”(我认为也是 VB.NET)。简单的答案是您创建的 localString 变量的范围在 foreach 内,因此每次迭代都使用它的一个新副本,但是在另一种情况下,您只需引用 s,最终会成为 c(在您打印之前)至少)。为了“解决”这类问题,我已经习惯了

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

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

于 2012-06-05T12:44:49.983 回答