我问了一个问题,其中一个响应包含以下LINQ代码:
var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x);});
有人可以解释上面的LINQ到新手吗?
答案 0 :(得分:5)
LINQ运算符使用所谓的fluent interface,因此您可以将第一行读作一系列函数调用。假设lstAvailableColors
是IEnumerable<T>
,我们的想法是每个可用的颜色都流经LINQ运算符。
让我们分解一下:
var selected = lstAvailableColors
// each item is cast to ListItem type
.Cast<ListItem>()
// items that don't pass the test (Selected == true) are dropped
.Where(i => i.Selected)
// turn the stream into a List<ListItem> object
.ToList();
编辑:正如JaredPar指出的那样,上面的最后一行(ToList()
)非常重要。如果您没有这样做,那么两个selected.ForEach
调用中的每一个都将重新运行查询。这称为deferred execution,是LINQ的重要组成部分。
您可以像这样重写第一行:
var selected = new List<ListItem>();
foreach (var item in lstAvailableColors)
{
var listItem = (ListItem)item;
if (!listItem.Selected)
continue;
selected.Add(listItem);
}
最后两行只是编写foreach循环的另一种方式,可以重写为:
foreach (var x in selected)
{
lstSelectedColors.Items.Add(x);
}
foreach (var x in selected)
{
lstAvailableColors.Items.Remove(X);
}
学习LINQ最困难的部分可能是学习数据流和lambda expressions的语法。
答案 1 :(得分:3)
原始问题的解释。
LINQ版本分为两部分。第一部分是第一行,它找到当前选定的项目并将值存储在List中。该行包含.ToList()调用非常重要,因为这会强制查询立即执行而不是延迟执行。
接下来的两行迭代选中的每个值,然后将其删除或添加到相应的列表中。因为已经存储了所选列表,所以当我们修改它时,我们不再枚举该集合。
答案 2 :(得分:2)
它将列表中的每个项目转换为ListItem类型,然后仅选择其Selected属性为true的项目。然后它创建一个仅包含这些项目的新列表。对于结果列表中的每个项目,它会将该项目添加到所选颜色列表中,并将其从可用颜色列表中删除。
答案 3 :(得分:1)
也许有些翻译会有所帮助
var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
可以写成:
List<ListItem> selected = new List<ListItem>();
foreach (ListItem item in lstAvailableColors)
{
if (item.Selected)
selected.Add(item);
}
请注意,foreach
隐式地将列表中的项目转换为循环变量的任何类型,在本例中为ListItem
,以便处理列表中的Cast<ListItem>
。 Where
过滤掉表达式为false
的所有项目,因此我使用if
语句执行相同的操作。最后,ToList
将序列转换为列表,所以我只是建立一个列表。最终结果是一样的。
和
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x); });
可以写成:
foreach (ListItem item in selected)
{
lstSelectedColors.Items.Add(item);
lstAvailableColors.Items.Remove(item);
}
我怀疑在这种情况下是否有充分的理由将其写成更为模糊的方式。