列表(或集合)项知道它的父列表的最有效方式

本文关键字:列表 方式 有效 集合 | 更新日期: 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);