问题描述
|
我目前正在从事的项目要求我创建一个树数据结构。
以下是我尝试实现此功能的示例。我决定创建一个子节点集合作为嵌套类,因为它允许我在其Add()方法中设置Nodes父对象,同时保持父设置者为私有,以便从Node派生的类或同一类中的其他类程序集无法直接访问它。
class Node<T> where T : Node<T>
{
private T mParent;
private ChildNodeCollection<T> mChildren;
public T Parent
{
get{return this.InnerParent;}
}
private T InnerParent
{
get{return this.mParent;}
set {this.mParent = value;}
}
public Node()
{
this.mChildren = new ChildNodeCollection<T>(this);
}
class ChildNodeCollection<U> where U : T
{
private U mParent;
public U CollectionParent
{
get{return this.mParent;}
}
public ChildNodeCollection(U parent)
{
this.mParent = parent;
}
public void Add(U item)
{
item.InnerParent = this.CollectionParent;
...
}
}
}
这段代码无法编译。它抱怨Node构造函数中的“ 1”行。它引发了这两个错误。
Error 35 The best overloaded method match for Node<T>.ChildNodeColllection<T>.ChildNodeColllection(T)\' has some invalid arguments
Error 36 Argument \'1\': cannot convert from Node<T> to T
我想即使我在类定义中指定了T也不能算出T是Node。我很好奇是否有人知道如何以不同的方式进行操作,该方式允许我在将Node \的parent添加到集合时设置Node的parent,而不会过多暴露内部访问修饰符的Node的Parent属性。
解决方法
无论如何,在使用构造函数创建泛型对象时,您需要显式指定type参数,因此您需要编写如下内容:
this.mChildren = new ChildNodeCollection<T>(this);
这是行不通的,因为this
的类型是Node<T>
而不是T
(这是构造函数的要求)。我认为最简单的解决方法是将父级存储为Node<T>
而不是使用通用参数。
代码的相关部分如下所示:
public Node() {
this.mChildren = new ChildNodeCollection(this);
}
class ChildNodeCollection {
private Node<T> mParent;
public ChildNodeCollection(Node<T> parent) {
this.mParent = parent;
}
}
我想您的最初目标(使用T : Node<T>
约束)是使用继承定义更特定类型的节点。然后,您想让静态类型为T
的孩子(或父母)进入(即您的特定节点类型)。我可能是错的,但我严重怀疑可以使用.NET泛型来表达这一点。
我认为使用Node<T>
作为表示包含T
类型值的节点的类型比使用继承要容易得多。
,您正在指定一个约束,该约束说U必须从T继承。
当您尝试执行this.mChildren = new ChildNodeCollection(this)
时,U被隐式定义为该类型(Node<T>
)。但是T没有定义。
,我相信可以用ѭ15解决
class Node<T>
{
protected Node<T> _parent;
protected List<Node<T>> _children;
protected T _value;
protected Node() { }
public Node(T value)
{
_parent = null;
_value = value;
_children = new List<Node<T>>();
}
public void AddChild(Node<T> child)
{
child._parent = this;
_children.Add(child);
}
}
class NaughtyNode : Node<int>
{
//Naughty nodes dont have parents,only kids
public NaughtyNode(int value)
{
_value = value;
_children = new List<Node<T>>();
}
public void BeNaughty()
{
Node<int> victim = new Node<int>(1);
victim._parent = this; //Does not work,cannot access
}
public void AddChild(NaughtyNode child)
{
_children.Add(child);
}
}
protected
仅允许Node<T>
中的代码对其进行访问。 NaughtyNode
看不到Node<T>
的_parent
。