我编写了以下C#代码:
I have written the following C# code:
_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); }此代码旨在创建一个字典,以我的区域ID"作为键,并以位置ID"列表作为值.
This code is meant to create a a dictionary with my "region ids" as keys and lists of "location ids" as values.
但是,实际上发生的是,我得到了一个以区域ID"作为键的字典,但是每个键的值都相同:这是regionIds中最后一个区域ID的位置列表!
However, what actually happens is that I get a dictionary with the "region ids" as keys, but the value for each key is identical: it is the list of locations for the last region id in regionIds!
这似乎是lambda表达式如何求值的产物.我可以通过将位置ID列表转换为数组来获得正确的结果,但这听起来像是一团糟.
It looks like this is a product of how lambda expressions are evaluated. I can get the correct result by casting the list of location ids to an array, but this feels like a kludge.
处理这种情况的最佳做法是什么?
What is a good practice for handling this situation?
推荐答案您正在使用LINQ.您需要执行急切的操作才能使其执行.Select. ToList()是执行此操作的好方法.列表是通用的,可以直接分配给IEnumberable.
You're using LINQ. You need to perform an eager operation to make it perform the .Select. ToList() is a good operator to do that. List is generic it can be assigned to IEnumberable directly.
在使用LINQ的情况下,默认情况下会进行惰性评估. ToList/eager操作强制执行选择.在使用这些操作符之一之前,不会执行任何操作.就像在ADO.NET中执行SQL一样.如果您有从用户中选择*"语句,那么在您执行其他操作之前实际上不会执行查询. ToList使选择执行.
In the case where you're using LINQ it does lazy evaluation by default. ToList/eager operations force the select to occur. Before you use one of these operators the action is not performed. It is like executing SQL in ADO.NET kind of. If you have the statement "Select * from users" that doesn't actually perform the query until you do extra stuff. The ToList makes the select execute.
更多推荐
如何迫使我的lambda表达式尽早评估?修复lambda表达式怪异?
发布评论