7

So, I'm trying to have a parent/child class relationship like this:

class ParentClass<C, T> where C : ChildClass<T>
{
    public void AddChild(C child)
    {
        child.SetParent(this); //Argument 1: cannot convert from 'ParentClass<C,T>' to 'ParentClass<ChildClass<T>,T>'
    }
}
class ChildClass<T>
{
    ParentClass<ChildClass<T>, T> myParent;
    public void SetParent(ParentClass<ChildClass<T>, T> parent)
    {
        myParent = parent;
    }
}

But, this is a compile error. So, my second thought was to declare the SetParent method with a where. But the problem is that I don't know what type declare myParent as (I know the type, I just son't know how to declare it.)

class ParentClass<C, T> where C : ChildClass<T>
{
    public void AddChild(C child)
    {
        child.SetParent(this);
    }
}
class ChildClass<T>
{
    var myParent; //What should I declare this as?
    public void SetParent<K>(ParentClass<K,T> parent) where K : ChildClass<T>
    {
        myParent = parent;
    }
}
Jay
  • 983
  • 2
  • 8
  • 23

1 Answers1

4

This seems to compile, though it's rather hairbrained:

class ParentClass<C, T> where C : ChildClass<C, T>
{
    public void AddChild(C child)
    {
        child.SetParent(this);
    }
}
class ChildClass<C, T> where C : ChildClass<C, T>
{
    ParentClass<C, T> myParent;
    public void SetParent(ParentClass<C, T> parent)
    {
        myParent = parent;
    }
}

This solution makes use of a recursively bound type parameter, which approximates the "self-type".

I'm obligated to link to Eric Lippert's article on this pattern: Curiouser and curiouser

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
  • Ok, but then you get the same problem I had with my second bit of code: how would I declare a variable of either the parent class or the child class? – Jay May 31 '13 at 01:24
  • 1
    I don't think you can. You would need derived classes that resolved the type parameters. I wrote about this pattern (albeit in Java) here, including its pitfalls: http://stackoverflow.com/a/7355094/697449 – Paul Bellora May 31 '13 at 01:45
  • Your problem could also be looked at as a design issue, but your question is currently very abstract. Consider updating with the actual use case, and maybe people can chime in on alternatives. – Paul Bellora May 31 '13 at 01:47
  • 1
    This works: `class ChildClass : ChildClass, T> { }`. Gives me the functionality I had originally wanted too. – Jay May 31 '13 at 01:51
  • Oh, I know it's a design issue. At least in the scope I'm using it. It's a bit late for that though. This solution works perfect though. – Jay May 31 '13 at 01:53
  • The *Curiouser and curiouser* post was exactly what I needed. – Andrew Keeton Dec 05 '18 at 21:57