6

So I have a tree class:

public class Tree<T> : IEnumerable where T : IComparable<T>
{
    private Node<T> root = null;

    ...

    private class Node<T> : IEnumerable<T> where T : IComparable<T>
    {
        private Node<T> left, right;
        ...
    }
}

It works fine, but I get the compiler warning: Type parameter 'T' has the same name as the type parameter from outer type 'Tree<T>' Well, of course it's the same name, they should be the same type. (In fact, since the Node class is private and thus can never be accessed outside of the Tree class, they are guaranteed to be the same type. Is this compiler warning just BS which I can safely ignore? Or is there some good reason why I should give the inner class a different generic name (other than just to make the warning go away)?

(I saw this question, which is about the warning itself, but this is clearly a different scenario. The types are guaranteed to be the same, as Node's are only created and accessed within the context of Tree, so there's no chance of confusion.)

Community
  • 1
  • 1
Darrel Hoffman
  • 4,436
  • 6
  • 29
  • 41

2 Answers2

10

You're misunderstanding nested type parameters.

The compiler is warning you about constructed types like Tree<int>.Node<string>. Such types will make your life miserable. (I speak from personal experience)

If you want to use the outer T in Node, you shouldn't make Node generic.

In general, there are very few reasons to nest one generic type within a different one.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    It'd be impossible to construct such a type, though, since `Node` is private. (Okay, I suppose `Tree` could construct one internally, but it doesn't, so no worries.) – Darrel Hoffman Jun 17 '13 at 19:46
  • @DarrelHoffman Why wouldn't any of the omitted `...` construct a `Node`? –  Jun 17 '13 at 19:48
  • 1
    @hvd Yes, what I meant was it _could_ construct a `Node` _with a different type_, but it doesn't. It only creates `Node`'s. If I were to do something as loony as `Tree.Node`, I'd expect errors or at least warnings, but that doesn't happen ever. – Darrel Hoffman Jun 17 '13 at 19:53
  • @DarrelHoffman: But it could happen, and the compiler warns you that it might happen. (before it's too late, so to speak) – SLaks Jun 17 '13 at 19:59
4

What you want is probably:

public class Tree<T> : IEnumerable where T : IComparable<T>
{
    private Node root = null;

    ...

    private class Node: IEnumerable<T>
    {
        private Node left, right;
        ...
    }
}

If you want the inner class to have the same T, you dont need to redefine it again.

fcuesta
  • 4,429
  • 1
  • 18
  • 13