void.pointer
void.pointer

Reputation: 26315

How to inherit from a generic parameter?

I'm basically wanting to do this:

class UILockable<T> : T
    where T : UIWidget
{
}

However, this doesn't work. I've seen people recommend that you do this:

class UILockable<T>
    where T : UIWidget
{
    private T _base;
}

This would require me to override each function UILockable would need and forward it to T. This is impossible since T may derive from UIWidget and have unique abstract/virtual methods of its own.

Is there no way to simply inherit from T?

Upvotes: 28

Views: 26043

Answers (4)

Kent Boogaart
Kent Boogaart

Reputation: 178630

No, there is not. However, I don't really understand your argument against having UILockable<T> inherit from UIWidget and forward all calls onto your T:

class UILockable<T> : UIWidget
    where T : UIWidget
{
    private readonly T t;

    public void SomeMethod()
    {
        this.t.SomeMethod();
    }
}

You don't care about the specifics of T's implementation of UIWidget - only that it is an implementation of UIWidget.

Upvotes: 4

this. __curious_geek
this. __curious_geek

Reputation: 43207

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. .Net generics are way different from C++ templates.

And when you're so sure that type argument T is going to be of type UIWidget then why not inherit from UIWidget itself. Should it ever be allowed [assuming, just assuming, I know this will never be possible] what would you achieve by inheriting your class from T that is already of type UIWidget. At design time, you'll only code against UIWidget, so why not directly inherit from UIWidget.

Upvotes: -1

Rodrick Chapman
Rodrick Chapman

Reputation: 5543

Think about it this way: When Type B inherits from type A, you're declaring that B is similar to A (where similarity means that you can use B everywhere you expect to use A). Now because such similarity is not symmetric you have that B is similar to A but A is not similar to B. Furthermore, B and C can both be similar to A (i.e. they both descend from A) without being similar to each other.

So what you want to declare is that Unlockable is similar to everything that is similar to UIWidget, but that's impossible because type similarity is not transitive (i.e. if B is similar to A and C is similar to A you can't say B is similar to C).

Upvotes: 4

Mehrdad Afshari
Mehrdad Afshari

Reputation: 421968

You can't inherit from the generic type parameter. C# generics are very different from C++ templates. Inheriting from the type parameter requires the class to have a completely different representation based on the type parameter, which is not what happens with .NET generics. They are identical at the IL and native level (for all reference type arguments).

Upvotes: 28

Related Questions