3

I have a generic type G<T> where T : A, where A is an abstract class. In each class B derived from A I want to have a field of type G<B>, without writing repetetive code, however I'm not sure if it's even possible. One way to do this would be

abstract class A
{
    protected object g;

    protected abstract void SetG();

    public A()
    {
        SetG();
    }
}

class B : A
{
    protected override void SetG()
    {
        this.g = new G<B>();
    }

    public B() : base() {}
}

But this would mean a lot of repetetive code in every derived class. Is there a better way to do this?

Dunno
  • 3,632
  • 3
  • 28
  • 43

2 Answers2

7

You could add an extra abstract class in between:

public abstract class A<T> : A where T : A
{
    protected override void SetG()
    {
        this.g = new G<T>();
    }
}

...then, update your B declaration to:

public class B : A<B>
{
    public B() : base() { }
}
wablab
  • 1,703
  • 13
  • 15
  • Hm yes that's certainly a better solution than mine. Thanks! I'll wait some time in case someone else thinks of something – Dunno Jun 15 '16 at 20:52
  • 2
    This is the solution you are looking for. You might want to think about just naming the between class something like `A` though. If you want to see this pattern somewhere else you can look at the Collections and their Generic implementations also. – Matt Rowland Jun 15 '16 at 20:55
  • Ha! Good point, @MattRowland! Not sure how that escaped me. :) Updating the answer to use that name instead. Thanks! – wablab Jun 15 '16 at 20:56
  • Actually, I think I'll just change `A` to `A`. Thanks guys, this is a really clever way to "tell" the base class what's deriving from it. – Dunno Jun 15 '16 at 21:00
0

I believe that what you are trying to do is a Covariant Conversion. See this MSDN article on using delegates and see if that works for you. Look in the section "Using Delegates with Covariant Type Parameters".

In your A:, create a delegate:

Func<G<A>> GetG;

Then, in your derived classes, set this func pointer to a function of type

Func<G<B>>

Bingo!

Community
  • 1
  • 1
Robert Columbia
  • 6,313
  • 15
  • 32
  • 40