带有泛型的嵌套类
本文关键字:嵌套 泛型 | 更新日期: 2023-09-27 17:57:50
我目前正在进行的项目要求我创建一个树数据结构。以下是我如何尝试实现此功能的示例。我决定创建一个子节点集合作为嵌套类,因为它允许我在它的Add()方法中设置Nodes parent,同时保持parent-setter私有,这样从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构造函数中的this.mChildren = new ChildNodeCollection(this)
行。它抛出了这两个错误。
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是Node,尽管我在类定义中指定了它。我很好奇是否有人知道如何以不同的方式完成这项工作,这样我就可以在将Node添加到集合时设置它的父级,而不会用内部访问修饰符过多地暴露Node的parent属性。
在任何情况下,使用构造函数创建泛型对象时都需要显式指定类型参数,因此需要编写以下内容:
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没有定义。
我相信使用protected
可以解决这个问题
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
。