1

I have a tree structure design problem, and i can't think of a way out.

i want to have one class Tree containing a generic data, and extend the Tree class with ComplexTree that will contain more methods like Iterate, DoSomthingOnComplex, etc.

here is a sample of the code i have:

class Tree<TData>
{
    public TData Data { get; set; }
    public ICollection<Tree<TData>> Children { get; private set; }

    public Tree<Data>(TData data)
    {
         // ...
    }

    public void Iterate(Action<TData> action)
    {
         action(Data);  
         Children.ForEach(x => x.Iterate(action));
    }
}

class ComplexTree<TData> : Tree<TData>
{
    public int ComplexValue1 { get; set; }
    public int ComplexValue2 { get; set; }

    public ComplexTree(TData data, int cv1, int cv2)
        : base(data)
    {
         // ...
    }

    public void DoComplexStuffOnTree()
    {
         // ... might want to use the base methods here
    }
}

problem is that for one thing, i can't really expose the collection that holds Tree to anyone that has create ComplexTree and i can't use Iterate for the ComplexTree because i can't use the cv1, cv2 values that belong only to the inheriting tree.

is there an obvious solution i'm missing? should i not use inheritance? should rewrite all the methods?

Thanks, John

4
  • Obvious question: If you want to add values to be stored in each node, why not just declare TData as a small class with a few properties? Commented Aug 14, 2010 at 20:30
  • 1
    I'll add that DoComplexStuffOnTree doesn't necessarily have to be a method of Tree or any of its children. It's an algorithm that's orthogonal to the implementation of the tree. Commented Aug 14, 2010 at 20:31
  • Stevem already said it, but define class ComplexData that holds those 2 complex values, then ComplexTree : Tree<ComplexData> so that TData becomes ComplexTree - then you can call Iterate or whatever on the base and it works fine Commented Aug 14, 2010 at 20:37
  • yes, i agree that all the methods i'd like to add are algorithms but we can all agree that each node in a tree is in itself a root of a tree and so i'd like to be able to use tree.DoSomething and not algorithms.DoSomthing(tree). but that leaves me with wondering why should i inherit from tree<data> anyway, since all the methods are in algorithms class the complex tree... i'm still not sure/convinced. Commented Aug 14, 2010 at 23:00

1 Answer 1

1

It is difficult to answer your question without knowing the actual use-case you need the tree structure for, but in general I would take sides with the suggestions made in the comments:

  • Declare a class ComplexData containing your two ints and declare ComplexTree as a subclass of Tree<ComplexData>.

  • You could even declare ComplexData<TData> itself generic so it can contain an additional TData, and then declare ComplexTree<TData> as a subclass of Tree<ComplexData<TData>>.

  • You need to be clear on the code contract for the methods that run your algorithms — i.e. what is the method actually supposed to do, in general/abstract terms, not in terms of a particular use-case. If the contract is that it returns a collection of TData objects, then obviously that is what it should do, irrespective of whether you are running it on a simple tree or a subclass. If the contract is more abstract and the behaviour should depend on the subclass, then maybe it should be a virtual method (or use protected virtual methods) that the subclasses can override.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.