列表(或集合)项知道它的父列表的最有效方式
本文关键字:列表 方式 有效 集合 | 更新日期: 2023-09-27 18:19:09
对于列表和其中的项,我发现需要在列表中查询或查找对象已添加到的内容。
例如:// create list of levels
IList<Levels> levels = new List<Levels>
{
levels.Add(new Level{ Depth = 1, Name = "Level 1" });
levels.Add(new Level{ Depth = 2, Name = "Level 2" });
}
foreach(Level level in levels)
{
bool lowestLevel = false;
// would the lowest level be best worked out from a function that takes the list and the level?
lowestLevel = Level.GetLowest(Levels, level);
// as a calculated property of level itself where the level knows about the list of levels it's in?
lowestLevel = Level.IsLowest;
// or worked out when creating the level?
// levels.Add(new Level{ Depth = 1, Name = "Level 1", IsLowest = isLowest });
lowestLevel = Level.IsLowest;
}
这些是"最佳实践"的方式来处理这样的事情,还是有其他的方法?
忽略添加到正在迭代的集合中会抛出异常的事实…
肯定有另一种方法。当一个Level
需要知道它的兄弟时,你应该把levels
封装在一个类中,比如LevelCollection
。当你在集合中插入一个关卡时,你可以给每个Level
一个对它的父集合的引用,并且在需要兄弟的方法中停止传递levels
。
为什么现在使用Linq:
lowest = list.Max(x => x.Level);
highest = list.Min(x => x.Level);
注意,如果你的列表是illist类型,一些Linq方法是不可用的。另外,如果你想获得实际的对象(Level),那么你必须使用如下命令:
var lowest = list.OrderBy(x => x.Level).First();
最佳实践是为适当的任务选择适当的结构。列表是非常常见的结构,没有任何特殊的功能。
所以在这种情况下,你应该有一些结构,当你添加元素时,它应该决定把它放在哪里。整个图论对你选择合适的解很有帮助。如果您发现了这样的结构,那么您必须检查它是否已经实现。. net框架包含了许多可能有用的通用结构。
所以你可以用SortedList代替List,你的Level类应该实现字典接口。
无论何时你将Level实例添加到这样的列表中,最低级别将在表的索引0下(或大小-1,这取决于你将使用的icomcomparable)
一篇关于c# 2.0数据结构的好文章
不要将Depth
存储在Level
类型上。而是传递对集合的引用。List.Add
方法中的Level.Parent = this;
。你总是可以通过List.IndexOf(Level)获得深度。这样,您就不需要在每次更改集合时将Depth更新为所有成员。
public class Level
{
public IList<Level> Parent { get; set; }
public string Name { get; set; }
}
public class LevelCollection : Collection<Level>
{
protected override void InsertItem(int index, Level item)
{
base.InsertItem(index, item);
item.Parent = this;
}
protected override void RemoveItem(int index)
{
this[index].Parent = null;
base.RemoveItem(index);
}
}
那么你就可以直接查询父元素来获取关卡中物品的深度。
this.Parent.IndexOf(this);