不同节点类型的树

时间:2014-07-05 14:25:08

标签: c# generics tree

我想在C#中构建一个树结构,其中每个节点都是泛型类型T的包装器。但我需要树中的层次关系不与T的类型绑定.i。

Interface INode<T> : Where T: AbstractNodeContent{
   T Value{get;set;}
   IList<INode<AbstractNodeContent>> Children {get;set;}
   INode<AbstractNodeContent> Parent {get;set;}
}
class abstract AbstractNodeContent{
}
class Region : AbstractNodeContent{
}
NodeRegion : INode<Region>{

   // field

   // contructor

   INode<AbstractNodeContent> getRoot(){
       return (i am root)? this : Parent.getRoot(); // compiler-error
   }
}

我尝试了很多不同的解决方案,但我总是被困在这里,我无法弄清楚我失踪了什么。 问题是在上面的函数getRoot()中我不知道哪个类型是根节点所以我需要一个INode&lt; AbstractNodeContent&GT;作为回报函数,所以当我返回这个时我有一个编译器错误,说我不能从这个转换为INode&lt; AbstractNodeContent取代。

这是可以实现的结果还是我必须重新考虑设计?我喜欢有一种不同类型的树的想法。关于如何考虑这种类型的设计以及如何实现它,你能给出一些建议吗?

感谢。 Luca Colombini

1 个答案:

答案 0 :(得分:1)

您之所以看到此原因,是因为您无法将Generic<SomeType>隐式转换为Generic<ParentType>。这是因为您有时会使用通用,有时会返回它,所以请参阅Contravariance and Covariance

尝试制作INode类型的接口或抽象类,没有通用参数,因此您可以通过引用此父级来获得该类的“任何进展”版本。

public abstract class Node { }
public abstract class Node<T> : Node { ... }

这样,您的GetRoot可以返回一个简单的节点。

如果您想要更加安全,请在父类中包含internal abstract成员,以便程序集之外的任何内容都不能实现非泛型父级。