vfa*_*bre 6 c# linq linq-group
我有以下方法。
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;
}
Run Code Online (Sandbox Code Playgroud)
在groupedItems集合中CalculatedValue,s 为空。但是,如果我在 s 具有值之后添加 a到句子ToList()中。例如:SelectGroupByCalculatedValue
var groupedItems = items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key)).ToList();
Run Code Online (Sandbox Code Playgroud)
所以,问题是。为什么是这样?我想知道这样做的原因,对我来说解决方案是添加一个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;
}
}
Run Code Online (Sandbox Code Playgroud)
var groupedItems = items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key));
Run Code Online (Sandbox Code Playgroud)
这里,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);
Run Code Online (Sandbox Code Playgroud)
例如,此代码将为 中的每个项目打印“Creating new item”两次items。
在您的代码中,您正在设置临时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);
Run Code Online (Sandbox Code Playgroud)
或者简单地使用对象初始值设定项
return items.GroupBy(i => i.Value)
.Select(x => new Item(x.First().Name, x.Key) { CalculatedValue = x.First().Name + x.Key });
Run Code Online (Sandbox Code Playgroud)
如果您想对进行计算的对象主题进行更多研究,请搜索术语“Monad”,但要做好被混淆的准备。
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |