我最近从vb.net切换到c#并继续碰到奇怪的事情。
这让我摸不着头脑,但可能很愚蠢,有人能指出我失踪了吗?
我有一个IEnumerable对象,其中包含实体,目前有3个实体。
AAA, orange, blue, red
BBB, green, yellow, pink
CCC, orange, pink, red
使用下面的代码我似乎得到了最后一个元素代码(三个字母),只有那个,三次。所以输出将是:
Running Company code: CCC
Running Company code: CCC
Running Company code: CCC
如果我单步执行,它会传递每一个,但我想它会在它放到控制台之前在foreach循环中改变它。如果我把console.writeline放在循环中,那么我将得到预期的结果。
Running Company code: AAA
Running Company code: BBB
Running Company code: CCC
我没有对它进行过测试,但我确信这在VB.Net中可以正常工作,有人可以解释我的遗失,它可能正好在我面前毫无疑问。
public void lookForWork()
{
var custs = _IRepository.GetCustomers();
var conf = _IRepository.GetConfig();
foreach (var custRow in custs)
{
worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.DoWork += (obj, e) => checkWork(conf.Where(x => x.Code == custRow.Code).SingleOrDefault());
worker.RunWorkerAsync();
}
}
private void checkWork(CustomerConfigEntity custInfo)
{
console.WriteLine(String.Format("Running Company code: {0}", custInfo.Code));
}
答案 0 :(得分:4)
你已经遇到了“封闭中的foreach循环变量”错误。
使用C#5.0,或写:
public void lookForWork()
{
var custs = _IRepository.GetCustomers();
var conf = _IRepository.GetConfig();
foreach (var custRow in custs)
{
var localCustRow = custRow;
worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.DoWork += (obj, e) =>
checkWork(conf.Where(x => x.Code == localCustRow.Code).SingleOrDefault());
worker.RunWorkerAsync();
}
}
有关更多信息,请参阅Eric Lippert关于此主题的优秀文章: http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx