我想知道这里出现了什么现象:
将List<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
答案 0 :(得分:-2)
这是C#中一个已知的“bug”(我认为也是VB.NET)。简单的答案是你创建的localString变量是在foreach中的作用域,因此每个itteration都会使用它的一个新副本,但在另一种情况下,你只需引用s,它最终会成为c(在你打印之前)最小)。为了“解决”这类问题,我已经做了一个实践
foreach(var _s = ....) {
var s = _s;
/* code here that uses s */
}
每次我都有这样的代表使用。