gpt4 book ai didi

c# - 为什么在 foreach 中对 Linq 分组选择所做的更改会被忽略,除非我添加 ToList()?

转载 作者:太空狗 更新时间:2023-10-30 01:03:23 34 4
gpt4 key购买 nike

我有以下方法。

public IEnumerable<Item> ChangeValueIEnumerable()
{
var items = new List<Item>(){
new Item("Item1", 1),
new Item("Item2", 1),
new Item("Item3", 2),
new Item("Item4", 2),
new Item("Item5", 3)
};

var groupedItems = items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key));

foreach (var item in groupedItems)
{
item.CalculatedValue = item.Name + item.Value;
}

return groupedItems;
}

groupedItems 集合中,CalculatedValue 为空。但是,如果我在 GroupBy 之后的 Select 句子中添加 ToList(),则 CalculatedValue 具有值。例如:

 var groupedItems = items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key)).ToList();

所以,问题来了。为什么是这样?我想知道这是为什么,我的解决方案是添加一个 ToList()

更新:Item类的定义如下

 public class Item
{
public string Name { get; set; }
public int Value { get; set; }

public string CalculatedValue { get; set; }

public Item(string name, int value)
{
this.Name = name;
this.Value = value;
}
}

最佳答案

var groupedItems = items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key));

在这里,groupedItems实际上不持有任何元素。 IEnumerable<T>Select 返回代表一个计算——准确的说,代表映射items的结果通过应用函数 x => new Item(x.First().Name, x.Key) 到一组新的项目.

每次迭代 groupedItems ,将应用该函数并创建一组新的项目。

var groupedItems = items.GroupBy(i => i.Value)
.Select(x =>
{
Console.WriteLine("Creating new item");
return new Item(x.First().Name, x.Key));
}

foreach(var item in groupedItems);
foreach(var item in groupedItems);

例如,此代码将为 items 中的每个项目打印两次“Creating new item” .

在您的代码中,您正在设置 CalculatedValue 短暂的项目。当 foreach 循环完成时,项目就消失了。

调用 ToList ,您正在将“计算”转化为实际的项目集合。

而不是调用 ToList ,您也可以创建另一个计算,表示一组新的项目及其 CalculatedValue属性集。这是功能性方式。

Func<Item, Item> withCalculatedValue =
item => {
item.CalculatedValue = item.Name + item.Value;
return item;
};

return items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key))
.Select(withCalculatedValue);

或者简单地使用对象初始化器

return items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key) { CalculatedValue = x.First().Name + x.Key });

如果你想对持有计算的对象做更多的研究,谷歌搜索术语“Monad”,但要做好被混淆的准备。

关于c# - 为什么在 foreach 中对 Linq 分组选择所做的更改会被忽略,除非我添加 ToList()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29392257/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com