在c#中用于类型安全树实现(类型安全节点)

时间:2016-10-17 00:21:11

标签: c# tree nodes type-safety

我正在寻找/ tring在C#中实现类型安全树实现。

如何在不使用接口(强制在整个地方重新实现树功能)和不使用强制转换的情况下实现类型安全树?

我有使用树作为公共基类的想法,但是类型安全性已经消失。我目前的方法是使用泛型。但我错过了一些转换回基类型。

以下是简化/非工作示例。 这个想法是返回的节点支持树函数,同时它们也支持它们的基类型行为。 我可以在没有Node的情况下使用下面的类,但是然后我一方面放松了类型安全,并且还因为节点已经有了父类而导致继承问题。

我还玩弄了课程扩展,但我还没有得到任何接近可能解决方案的东西。

我想我需要一些关于如何继续的小提示。先谢谢你。

public class Node<T>  // .
{
    public Node<T> parent;
    public List<Node<T>> children;

    protected Node()
    {
        children = new List<Node<T>>();
        parent = null;
    }
    protected Node(Node<T> parent)
        : this()
    {

        this.parent = parent;
        parent.addChildren(this);
    }


    protected void addChildren(Node<T> child)
    {
        children.Add(child);
    }
    public Node<T> getRoot() // returns root node
    public List<Node<T>> flatten()  // return 1d-list of all nodes.

}

2 个答案:

答案 0 :(得分:0)

  

我有使用树作为公共基类的想法,但是类型安全性已经消失。我目前的方法是使用泛型。但我错过了一些转换回基类型。

然后将泛型类型约束为基类型:

public class Node<T> where T: BaseType { ... }

现在,只要Node<MyDerivedType>派生自MyDerivedType,您就可以创建BaseType类型的任何树。

另一方面,我考虑在您的实施中修改以下内容:

  1. Children应该是一个属性,除非是readonly,否则不要公开字段。此外,您不应将其公开为List;这将允许任何人直接添加或删除节点,这可能违反您的实现中假定的不变量。请改为IEnumerable<T>

    private readonly List<T> children;
    public IEnumerable<T> Children => children.Select(c => c);
    

    您可以直接返回children,因为它可以隐式转换为IEnumerable<T>;问题是任何人都可以简单地将其强制转换回List<T>并进行修改。投射它可以保护您免受此转换。

  2. Flatten也是如此(第一个 f 应该大写btw)。考虑返回IEnumerable<T>

答案 1 :(得分:0)

这是一个类型安全的树实现:

public class Tree<T> : List<Tree<T>>
{
    public T Value { get; set; }
}

是的,就是这样。简单。

当然,您可以添加一个或两个构造函数,并使Value属性为只读,以使其更友好。您可以轻松添加Parent属性。