I found a question here that almost answers my question, but I still don't fully understand.
Trying to write a Tree data structure, I did this:
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>>();
}
...
}
}
And, anyone who's worked with C# generics apparently knows that I got this compiler warning: Type parameter 'T' has the same name as the type parameter from outer type 'Tree<T>'
My intent was to create an inner class that would be forced to use the same type as the outer class, but I now understand that adding a type parameter actually allows the inner class to be more flexible. But, in my case, I want subclasses of Tree<T>
to be able to use TreeNode
, for example, like this:
public class IntTree : Tree<int>
{
...
private static IntTree fromNode(TreeNode<int> node)
{
IntTree t = new IntTree();
t.root = node;
return t;
}
}
(That method allows the subclass to implement ToString()
recursively)
So my question is, if I take out the parameterization, like this:
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>();
}
...
}
}
will the resulting subclass be forced to use integers when creating TreeNode
s, and therefore never be able to break the intent I had?
Disclaimer: yes, I know I'm probably doing plenty of things wrong here. I'm still learning C#, coming from a mostly Java and Lisp background, with a little bit of plain C. So suggestions and explanations are welcome.