foreach 循环中的匿名委托
本文关键字:循环 foreach | 更新日期: 2023-09-27 18:36:15
可能的重复项:
的问题
关于每个和代表
我想知道这里发生了什么现象:
将List<string>
转换为返回相同字符串的委托列表会出错。
当我直接使用输入列表上的foreach
返回的变量时,这种情况WrongConversion
发生。 (每次返回列表中的最后一个字符串)
在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
这是
C# 中一个已知的"错误"(我认为也是 VB.NET 错误)。简单的答案是,您创建的localString变量的作用域在foreach内,因此每次迭代都使用它的新副本,但是在另一种情况下,您只需引用s,最终最终会得到c(至少在打印之前)。为了"解决"此类问题,我已经把它作为一种实践
foreach(var _s = ....) {
var s = _s;
/* code here that uses s */
}
每次我都使用这样的代表。