Dan*_*don 10 .net c# linq lambda
我写了以下C#代码:
_locationsByRegion = new Dictionary<string, IEnumerable<string>>();
foreach (string regionId in regionIds)
{
IEnumerable<string> locationIds = Locations
.Where(location => location.regionId.ToUpper() == regionId.ToUpper())
.Select(location => location.LocationId); //If I cast to an array here, it works.
_locationsByRegion.Add(regionId, LocationIdsIds);
}
Run Code Online (Sandbox Code Playgroud)
此代码用于创建一个字典,其中"region id"作为键,并将"location id"列表作为值.
然而,实际发生的是我得到一个字典,其中"region id"作为键,但每个键的值是相同的:它是regionIds中最后一个区域id的位置列表!
看起来这是lambda表达式如何计算的产物.我可以通过将位置ID列表转换为数组来获得正确的结果,但这感觉就像一个kludge.
处理这种情况的好习惯是什么?
m4t*_*mus 11
你正在使用LINQ.您需要执行急切操作才能使其执行.Select.ToList()是一个很好的运算符.列表是通用的,可以直接分配给IEnumberable.
在您使用LINQ的情况下,默认情况下会进行延迟评估.ToList/eager操作强制select发生.在使用其中一个运算符之前,不会执行该操作.这就像在ADO.NET中执行SQL一样.如果你有一个声明"Select*from users",它实际上不会执行查询,直到你做额外的事情.ToList使select执行.
你关闭变量而不是值.
制作变量的本地副本,以便从foreach循环中捕获当前值:
_locationsByRegion = new Dictionary<string, IEnumerable<string>>();
foreach (string regionId in regionIds)
{
var regionToUpper = regionId.ToUpper();
IEnumerable<string> locationIds = Locations
.Where(location => location.regionId.ToUpper() == regionToUpper)
.Select(location => location.LocationId); //If I cast to an array here, it works.
_locationsByRegion.Add(regionId, LocationIdsIds);
}
Run Code Online (Sandbox Code Playgroud)
然后读这个:
http://msdn.microsoft.com/en-us/vcsharp/hh264182
编辑 - 强制进行急切的评估也会像其他人建议的那样有效,但大多数时候,热切的评估最终会慢得多.