有几个问题在这里。首先是Where语句不会生成对象列表。这是一个表达声明。
表达式语句即时评估,因此每次运行语句时都会丢弃对生成对象的更改。相信与否这是一个理想的结果。这允许您以更高效和优雅的方式处理复杂的嵌套for语句。
回答你的问题的最好方法是分析你写的东西,并重新编写一些代码给你展示一个更好的方法。
在您的代码:
List<Apple> apples = ...
var selectableApples = apples.Select(a => new SelectableApple { SelectedByPerson = null, Apple = a });
foreach (Person person in persons)
{
foreach (var unselectedApple in selectableApples.Where(aa => aa.SelectedByPerson == null))
{
// This will ideally give all apples to the first person who
// meets the conditions. As such this if condition can be moved
// out side of the above the foreach loop.
if (/*the person satisfies some conditions*/)
{
// This gets executed like 100 times:
unselectedApple.SelectedByPerson = person;
}
}
}
foreach (var selectedApple in selectableApples.Where(aa => aa.SelectedByPerson != null))
{
Unreachable code - the collection is empty... WTF???
}
因此,如果我们返工此代码,以便在内部循环的if语句不在身边。你的代码将做同样的逻辑事情。请注意,这还没有解决问题,但让你更靠近一步。下面是代码的外观:
List<Apple> apples = ...
var selectableApples = apples.Select(a => new SelectableApple { SelectedByPerson = null, Apple = a });
foreach (Person person in persons)
{
// Now we can see that since this will all apples to the first person
// who satisfies the below conditions we are still doing to much. And it
// still does not work.
if (/*the person satisfies some conditions*/)
{
foreach (var unselectedApple in selectableApples.Where(aa => aa.SelectedByPerson == null))
{
// This gets executed like 100 times:
unselectedApple.SelectedByPerson = person;
}
}
}
foreach (var selectedApple in selectableApples.Where(aa => aa.SelectedByPerson != null))
{
Unreachable code - the collection is empty... WTF???
}
现在我们已经开始组的东西,这样一个简单的答案就可以看出。由于if语句意味着只有满足条件的第一个人才是获得所有苹果的人。所以让我们摆脱外部的foreach循环,并将其凝聚到LINQ。
List<Apple> apples = ...
var selectableApples = apples.Select(a => new SelectableApple { SelectedByPerson = null, Apple = a });
var selectedPerson = persons.Where(p => /*the person satisfies some conditions*/).First()
if(selectedPerson != null)
{
foreach (var unselectedApple in selectableApples.Where(aa => aa.SelectedByPerson == null))
{
// This gets executed like 100 times:
unselectedApple.SelectedByPerson = person;
}
}
foreach (var selectedApple in selectableApples.Where(aa => aa.SelectedByPerson != null))
{
Unreachable code - the collection is empty... WTF???
}
看着上面的代码,我们现在可以看到的是,内环仅仅是对原选择的修改。所以让我们看看:
List<Apple> apples = ...
var selectedPerson = persons.Where(p => /*the person satisfies some conditions*/).First()
var selectableApples = apples.Select(a => new SelectableApple { SelectedByPerson = selectedPerson, Apple = a });
foreach (var selectedApple in selectableApples.Where(aa => aa.SelectedByPerson != null))
{
// This should now run provided that some person passes the condition.
}
现在您的代码将按需要运行,并且您可以利用LINQ中提供的延迟加载和循环优化。
混合投影和突变?这条100倍线只能在事物的阴影下运作,而不是事物本身。 – bzlm
你确定SelectableApple是一个“类”,而不是“结构”? –