我现在正在桌子上敲打几个小时,但是在C#中实现树形结构似乎太愚蠢了。
Node
和NodeCollection
。Node
和NodeCollection
都可以有父NodeCollection
NodeCollection
可以有一组子节点,可以是Node
或NodeCollection
Node
不能有任何孩子。Node
或NodeCollection
被视为根节点 Node
具有任何任意类型的值,使用泛型
BCL的集合类型是否有此目的?到目前为止我所拥有的:
public abstract class NodeBase {
protected NodeCollection Parent { get; set; }
}
public class Node<T> : NodeBase {
public string Key { get; set; }
public T Value { get; set; }
}
public class NodeCollection : NodeBase {
public ICollection<NodeBase> Children { get; set; }
}
这个解决方案“有效”,但我不能只是走下树,因为NodeBase
没有提供任何子项。我必须验证类型以查明子节点是否为NodeCollection
,但如果不是,则无法正确转换Node
,因为它可能是未知类型。
答案 0 :(得分:5)
最简单的选择是只有一个Node
类(而不是有两种类型的节点,将叶子与非叶子节点分开),并让你的叶子节点只有一个空的子集合而不是根本没有收集。
如果出于其他原因拥有这两种类型的节点很重要,那么您希望让它们都实现一个定义子集合的接口,叶子节点将返回到该接口一个空的集合。
答案 1 :(得分:0)
为了处理Node没有到集合的链接,我使用了一个名为&#34; HasChildren&#34;的抽象基类属性。允许检查,并确保如果您忘记检查并尝试访问子项,具体的Node实现会抛出异常。
public abstract class NodeBase<T> {
public abstract bool HasChildren { get; }
public abstract ICollection<T> Children { get; set; }
}
public class NodeCollection<T> : NodeBase<T> {
public override bool HasChildren { get { return true; } }
public override ICollection<T> Children { get; set; }
}
public class Node<T> : NodeBase<T> {
public override bool HasChildren { get { return false; } }
public override ICollection<T> Children { get { throw new Exception("blah"); } set { throw new Exception("blah"); } }
}
我使用抽象基类方法中的Add
方法具体实现来计算要添加的内容,以及如何对我来说,它还负责将项目添加到NodeCollections的集合排序,并在需要时强制执行唯一性