通常使用列表及其中的项目,我发现需要在列表中查询或查找已添加对象的内容。
例如:
// 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;
}
这些都是最好的做法吗?处理这样的事情的方法还是有另一种方式?
提前致谢。
答案 0 :(得分:2)
忽略添加到正在迭代的集合抛出异常的事实......
肯定有另一种方式。当Level
需要了解其兄弟姐妹时,您应该将levels
封装在一个类中,比如LevelCollection
。当您将一个级别插入到集合中时,您可以为每个Level
提供对其父集合的引用,并停止在方法中传递levels
而不是兄弟姐妹。
答案 1 :(得分:1)
为什么现在使用Linq:
lowest = list.Max(x => x.Level);
highest = list.Min(x => x.Level);
请注意,如果列表的类型为IList,则某些Linq方法不可用。此外,如果你想获得实际的对象(Level),那么你必须使用类似的东西:
var lowest = list.OrderBy(x => x.Level).First();
答案 2 :(得分:0)
最佳做法是为正确的任务选择合适的结构。 List是非常常见的结构,没有任何特殊功能。
所以对于这种情况你应该有一些结构,当你添加元素时,它应该决定放置它的位置。整个图论对您选择合适的解决方案非常有帮助。如果您找到这样的结构,那么您必须检查是否已经实现。 .NET Framework包含许多可能有用的常见结构。
因此,您可以使用List代替SortedList,而您的Level类应该实现IDictionary接口。
每当您将Level实例添加到此类列表时,最低级别将位于表的索引0下(或大小为-1,这取决于您将使用的IComparable)
的好文章答案 3 :(得分:0)
不要将Depth
存储在Level
类型上。而是传递对集合的引用。
Level.Parent = this;
方法中的List.Add
。您总是可以通过List.IndexOf(级别)获得深度。这样,每次更改集合时,都不需要将深度更新为所有成员。
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);