Nikita Goncharuk
Nikita Goncharuk

Reputation: 815

Generic Class inherit from T

Can I inherit my class from a generic type T? For example:

public abstract class BasePage<T> : T, IDisposable where T : Page 
{
    // Realization
}

I need to do this to provide basic functionality to other types of pages.

public class ContentBasePage : BasePage<ContentPage>
{ }

public class TabbedBasePage : BasePage<TabbedPage>
{ }

But I need to have ContentBasePage inherited from ContentPage, TabbedBasePage is inherited from TabbedPage. This is necessary to use this class in the Xaml markup. I can create a shared interface IBaseType, but the code will be duplicated

My full BasePage class, this isn't work:

public abstract class BasePage<T> : IDisposable where T : Page
{
    #region Private Fields

    protected BaseViewModel BaseViewModel { get; private set; }

    #endregion


    #region Init / Dispose

    ~BasePage()
    {
        Dispose();
    }

    public void Dispose()
    {
        BaseViewModel?.Dispose();
    }

    #endregion


    #region Public Methods

    public void SetViewModel(BaseViewModel viewModel)
    {
        BindingContext = BaseViewModel = viewModel;
    }

    #endregion


    #region Override Methods

    protected override void OnAppearing()
    {
        base.OnAppearing();
        Task.Run(async () => {
            await Task.Delay(50); // Allow UI to handle events loop
            if (BaseViewModel != null)
                await BaseViewModel.OnPageAppearing();
        });
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        Task.Run(async () => {
            await Task.Delay(50); // Allow UI to handle events loop
            if (BaseViewModel != null)
                await BaseViewModel.OnPageDissapearing();
        });
    }

    #endregion
}

Upvotes: 1

Views: 4376

Answers (2)

sbp
sbp

Reputation: 973

Since the title of this question was 'Generic Class inherit from T', it looked like duplicate of this StackOverflow post but sounds like you are just after a pattern to avoid duplication (based on your comment on your own question and no reference to T in the code example of BasePage<T> that you put in question). In that case I wouldn't use generic. It would become simple case of inheritance. Would following solution work for you?

public class Page
{
    public string PageProperty { get; set; }
}
public abstract class BasePage : Page, IDisposable
{
    public void Dispose()
    {
    }
}

public class ContentPage : BasePage
{
    public string ContentProperty { get; set; }
}

public class TabbedPage : BasePage
{
    public string TabbedProperty { get; set; }
}

public class ContentBasePage : ContentPage{}

public class TabbedBasePage : TabbedPage{}

Upvotes: 0

Mong Zhu
Mong Zhu

Reputation: 23732

Can I inherit my class from T class?

You cannot inherit from T since it is just a placeholder for a type. The compiler will not know what structure to apply because there is none.

The documentation says:

a type parameters is a placeholder for a specific type that a client specifies when they instantiate a variable of the generic type. A generic class, such as GenericList listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type.

You need to remove the T from the inheritance declaration:

public abstract class BasePage<T> : IDisposable where T : Page

But you can inherit from a generic class like in your example BasePage<T>. When you do this you have to specify the type of T in the derived class like you did:

public class ContentBasePage : BasePage<ContentPage>

Your code will work if ContentPage and TabbedPage inherit from Page

Upvotes: 3

Related Questions