【发布时间】:2020-04-24 09:27:31
【问题描述】:
我正在尝试对对象列表进行分组,这些对象具有一个列表属性。使用以下表达式时,它不会将具有列表的对象分组在一起,大概是因为当它检查每个列表的相等性时,它不匹配 - 即使内容相同。
我知道这是问题所在,就好像我停止对列表进行分组一样,代码输出两项而不是三项。
如何调整我的表达方式,以便正确地将前两项(相同的)归为一组?
public class Item {
public string Id { get; set; }
public string Name { get; set; }
public IEnumerable<ChildItem> Children { get; set; }
}
public class ChildItem {
public string ChildItemName { get; set; }
}
var items = new List<Item> {
new Item {
Id = "00001",
Name = "My Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 1" },
new ChildItem { ChildItemName = "string 2" },
}
},
new Item {
Id = "00001",
Name = "My Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 1" },
new ChildItem { ChildItemName = "string 2" },
}
},
new Item {
Id = "00002",
Name = "My Second Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 3" },
}
}
};
var result =
from c in items
group c by new
{
c.Id,
c.Name,
c.Children,
}
into gcs
select new Item()
{
Id = gcs.Key.Id,
Name = gcs.Key.Name,
Children = gcs.Key.Children
};
【问题讨论】:
-
覆盖
Equals&GetHashCode为ChildItem。 -
不要听@JohnathanBarclay 的建议,除非你 100% 确定你在做什么,这两个覆盖是什么意思,并且 100% 确定这不会与其他任何东西发生冲突或导致问题在代码的其他部分。根据您的域逻辑,您可能希望在不同的地方以不同的方式“比较”相同的事物。那些
overrides不会让你这样做。此外,有很多代码(库)依赖 .Equals 和 .GetHashCode 来处理各种事情,并且覆盖 .Equals 可能会导致细微的错误。使用 Olivier 的回答中的IEqualityComparer<>。更安全。 -
我已经编辑了标题以使其更清晰一些。我认为“Group .. with IEnumerable Properties”并没有说明您想要实现的目标。另外,除非必要,我们通常不会在标题中包含关键字,因此我从标题中删除了 C# 和 LINQ 标记 (meta.stackexchange.com/questions/19190/…)。当然,您可以随意重新编辑标题,或者根据需要将其回滚。
-
你为什么不按
Id而不是Children比较对象?比较ints 比比较Lists 效率更高。