C# 最有效的恢复方法是什么;“亲子关系”;关系树?

C# 最有效的恢复方法是什么;“亲子关系”;关系树?,c#,algorithm,C#,Algorithm,我有一门课: class DisplayableUnit { public string ID; //unique ID which is not repeated public string ParentID; //ID of parent DisplayableUnit [NonSerialized] public DisplayableUnit ParentDU; //Instance of parent displayable unit //ot

我有一门课:

class DisplayableUnit
{
    public string ID; //unique ID which is not repeated
    public string ParentID; //ID of parent DisplayableUnit
    [NonSerialized]
    public DisplayableUnit ParentDU; //Instance of parent displayable unit

    //other fields
}
此类的每个实例都存储在列表中。 在某个时刻,我将这些实例中的每一个序列化为一个单独的文件,然后将其重新加载。 当然,ParentDU字段变成了null,我真的不需要对它进行序列化

现在,我的任务是恢复实例之间的关系,因此我寻找一种最清晰、最快速的方法

我拥有的是一个包含所有反序列化对象的列表LoadedProject.DUnits**

我写了一些函数来做这件事,但使用这些函数仍然感觉有点奇怪和浪费时间

private static List<DisplayableUnit> GetChildDisplayableUnitsFor(DisplayableUnit dunit)
{
    List<DisplayableUnit> ret_list = new List<DisplayableUnit>();

    for (int i = 0; i < LoadedProject.DUnits.Count; i++) //iterate through all deserialized units
        if (string.Compare(LoadedProject.DUnits[i].ParentDUnitID, dunit.ID) == 0) //compare the own ID and parentID of potential child
            ret_list.Add(LoadedProject.DUnits[i]); //add to list if this is child

    return ret_list;
}

public static void RestoreTreeForDU(DisplayableUnit du)
{
    List<DisplayableUnit> childs = GetChildDisplayableUnitsFor(du); //get childs units

    for (int i = 0; i < childs.Count; i++) //iterate through those
    {
        childs[i].ParentDUnit = du; //restore instance link
        RestoreTreeForDU(childs[i]); //make just found child as parent and see if we can restore childs for it.
    }
}

public static List<DisplayableUnit> GetParentDUnits()
{
    List<DisplayableUnit> ret_list = new List<DisplayableUnit>();

    for (int i = 0; i < LoadedProject.DUnits.Count; i++)
        if (string.IsNullOrEmpty(LoadedProject.DUnits[i].ParentDUnitID))
            ret_list.Add(LoadedProject.DUnits[i]);

    return ret_list;
}
私有静态列表GetChildDisplayableUnits for(DisplayableUnit dunit) { List ret_List=新列表(); for(int i=0;i 这就是我开始思考下一步该做什么的地方。。。开始恢复关系时,我需要做些什么? 我是否只需要迭代LoadedProject.DUnits(所有反序列化单元)并为每个单元调用RestoreTreeForDU

这看起来有点奇怪,因为那里的一些单位已经恢复了等等。
这太令人困惑了:/

创建一个实际对象的ID查找,然后您可以简单地在列表中循环,并从该查找中获取其父对象的值:

List<DisplayableUnit> list = new List<DisplayableUnit>();
//todo deserialize into list

var lookup = list.ToDictionary(unit => unit.ID, unit => unit);
foreach (var unit in list)
    unit.ParentDU = lookup[unit.ParentID];
List List=新列表();
//todo反序列化到列表中
var lookup=list.ToDictionary(unit=>unit.ID,unit=>unit);
foreach(列表中的var单位)
unit.ParentDU=查找[unit.ParentID];

此类型不应该是
结构
,它几乎肯定应该是
。1) 可变结构是邪恶的2)该类型在语义上不表示单个值3)您希望在当前使用itOk时逻辑上表示对此对象的引用,谢谢。修好了。对不起,我没有其他州的人。我只想基于字符串ParentIDPersonally恢复每个实例的ParentDU,我会使用id作为键将所有
DisplayableUnit
推送到
字典中。然后遍历所有DU并查找相应的父级应该很容易。我还考虑是否可以向类中添加子级列表。从根开始查找子项(假设整个集合只有一个最终父项)可能比从子项返回到根更容易。@MattBurland任何一个方向都同样容易。如果你看一下我的解决方案,得到你描述的唯一改变就是将
改为dictionary
改为
改为ToLookup
,并交换
ID
ParentID
的所有用法。仅此而已!?这会还原所有内容的父实例吗?我不明白在第一行之后会发生什么事?>我不明白在ToDictionary方法中未定义单位的用法是什么。@Kosmos是的,就是这样,是的,它为每个项设置了所有父项。如前所述,它创建了一个查找,可以将单元ID映射到单元本身。它创建一个字典,遍历列表中的所有项,添加该项ID的新键,并向该单元添加引用值,然后再次遍历所有单元,查找其父项并设置相应的引用
unit
只是给匿名方法的参数起的名字。哦,等等,我需要Linq吗?编译器告诉我:
System.Collections.Generic.List”不包含“ToDictionary”的定义,并且找不到接受“System.Collections.Generic.List”类型的第一个参数的扩展方法“ToDictionary”(是否缺少using指令或程序集引用?)
@Kosmos:没有Linq也很容易,但它会长几行,而且Linq值得了解和喜爱。你可能是对的。我总是发现Linq解决方案非常小,但通常仍使用.NET2.0编写代码