我的任务是将功能添加到现有的代码库中。代码主要由刚离开我们团队的开发人员编写。考虑到这一点,我有一些限制:/。用C#管理人造树#
开发人员之前编写了一些代码,看起来像列表和树之间的交叉。在用户界面中,它是一个树形结构。但是,在代码中,它是一个List。它有点奇怪。两个主要的类定义如下:
public class TreeBranch
{
public Guid ID { get; set; }
}
public class TreeItem
{
public Guid ID { get; set; }
public Guid TreeBranchID { get; set; }
public Guid? ParentTreeItemID { get; set; }
public int Level { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? MarkedOn { get; set; }
}
所以,TreeBranch被存储在数据库中的表和TreeItem存储在数据库表中。执行一个查询,该查询返回所有TreeItem元素的特定TreeBranchID,其MarkedOn值为NULL。这是处理列表这样的:
List<TreeItem> treeItems = GetTreeBranchItems("someID");
treeItems.Sory(new TreeItemComparer());
我TreeItemComparer类如下所示:
public class TreeItemComparer: IComparer<TreeItem>
{
// allow us to look up parent Items by GUID
IDictionary<Guid, TreeItem> itemLookup;
public TreeItemComparer(IEnumerable<TreeItem> list)
{
itemLookup = list.ToDictionary(item => item.ID);
foreach (var item in list)
SetLevel(item);
}
public int SetLevel(TreeItem item)
{
if ((item.Level == 0) && (item.ParentTreeItemID != Guid.Empty))
{
if (itemLookup.ContainsKey(item.ParentTreeItemID))
item.Level = 1 + SetLevel(itemLookup[item.ParentTreeItemID]);
}
else if (item.ParentTreeItemID == Guid.Empty)
item.Level = 1;
return item.Level;
}
public int Compare(TreeItem x, TreeItem y)
{
// see if x is a child of y
while (x.Level > y.Level)
{
if ((x.ParentTreeItemID == y.ID) || (x.ParentTreeItemID == Guid.Empty))
return 1;
x = itemLookup[x.ParentTreeItemID];
}
// see if y is a child of x
while (y.Level > x.Level)
{
if ((y.ParentTreeItemID == x.ID) || (y.ParentTreeItemID == Guid.Empty))
return -1;
}
// x and y are not parent-child, so find common ancestor
while (x.ParentTreeItemID != y.ParentTreeItemID)
{
if (x.ParentTreeItemID != Guid.Empty)
x = itemLookup[x.ParentTreeItemID];
if (y.ParentTreeItemID != Guid.Empty)
y = itemLookup[y.ParentTreeItemID];
}
// compare createDate of children of common ancestor
return x.CreatedOn.CompareTo(y.CreatedOn);
}
}
此代码的工作,但有一个例外。偶尔,我会得到一棵破碎的树。举例来说,如果我有一个类似如下结构:
Item 1
Item 1-A (Imagine this TreeItem has a MarkedOn value that is NOT null)
Item 1-A-a
Item 1-A-a-1
Item 1-A-b
Item 1-B
好了,在上面的例子中,我只是真的应该具备以下条件:
Item 1
Item 1-B
但是,我越来越
Item 1
Item 1-A-a
Item 1-A-a-1
Item 1-A-b
Item 1-B
我的问题是,具有MarkedOn值的TreeItem和其所有的“children”不应该是集合的一部分。因为我们的环境,我不能碰数据库:(。与此同时,我不知道如何在代码中做到这一点。没有人有任何想法?
谢谢!
我没有看到MarkedOn依赖任何逻辑。既然你说的那个特定的代码位是什么打破,这将有助于将其列入。 – Guvante 2013-02-25 15:44:16