内部类泛型类型与外部类型相同
本文关键字:类型 外部 泛型类型 内部类 | 更新日期: 2023-09-27 17:59:50
我在这里发现了一个问题,几乎回答了我的问题,但我仍然没有完全理解。
试图编写一个Tree数据结构,我这样做了:
public class Tree<T>
{
public TreeNode<T> root;
...
public class TreeNode<T>
{
List<TreeNode<T>> children;
T data;
public T Data { get { return data; } }
public TreeNode<T>(T data)
{
this.data = data;
children = new List<TreeNode<T>>();
}
...
}
}
而且,任何使用过C#泛型的人显然都知道我收到了编译器警告:Type parameter 'T' has the same name as the type parameter from outer type 'Tree<T>'
我的意图是创建一个内部类,该类将被迫使用与外部类相同的类型,但我现在明白了,添加类型参数实际上可以使内部类更加灵活。但是,在我的情况下,我希望Tree<T>
的子类能够使用TreeNode
,例如:
public class IntTree : Tree<int>
{
...
private static IntTree fromNode(TreeNode<int> node)
{
IntTree t = new IntTree();
t.root = node;
return t;
}
}
(该方法允许子类递归地实现ToString()
)
所以我的问题是,如果我去掉参数化,像这样:
public class Tree<T>
{
public TreeNode root;
...
public class TreeNode
{
List<TreeNode> children;
T data;
public T Data { get { return data; } }
public TreeNode(T data)
{
this.data = data;
children = new List<TreeNode>();
}
...
}
}
生成的子类在创建TreeNode
s时是否会被迫使用整数,从而永远无法破坏我的意图?
免责声明:是的,我知道我可能在这里做错了很多事情。我仍在学习C#,主要来自Java和Lisp背景,有一点简单的C。因此,欢迎提出建议和解释
是的,它将被迫使用相同的类型。再次查看声明:
public class Tree<T>
{
public class TreeNode
{
private T Data;
}
}
因此,Data
的类型是在实例化特定的Tree
:时确定的
var tree = new Tree<int>();
通过这种方式,Data
的类型被声明为int
,并且不能有任何不同。
请注意,不存在非泛型TreeNode
类。只有一种Tree<int>.TreeNode
类型:
Tree<int> intTree = new Tree<int>(); // add some nodes
Tree<int>.TreeNode intNode = intTree.Nodes[0]; // for example
Tree<string> stringTree = new Tree<int>(); // add some nodes
Tree<string>.TreeNode stringNode = stringTree.Nodes[0]; // for example
// ERROR: this won't compile as the types are incompatible
Tree<string>.TreeNode stringNode2 = intTree.Nodes[0];
Tree<string>.TreeNode
是与Tree<int>.TreeNode
不同的类型。
在外部类中声明的类型T
可能已经在其所有内部声明中使用,因此您可以简单地从内部类中删除<T>
:
public class Tree<T>
{
public TreeNode root;
//...
public class TreeNode
{
List<TreeNode> children;
T data;
public T Data { get { return data; } }
public TreeNode(T data)
{
this.data = data;
children = new List<TreeNode>();
}
//...
}
}