Paul
Paul

Reputation: 620

Inheritance & BASE Classes in ASP.NET MVC

I’m trying to understand inheritance within an MVC application and I have a couple of things I would like clear up if someone can please help.

Question 1

If I have the following three classes which inherit off each other as follows

Public class StandardPage

Public class ArticlePage : StandardPage

Public class NewsPage : ArticlePage

Is the StandardPage class the only BASE class here or is the ArticlePage class also referred to as a BASE class because the NewsPage class derives from it?

In a nut shell are classes that derive from other classes also referred to as BASE classes (for the class that inherits it)?

Question 2

If I have the above classes defined when working in the strongly typed view file (with Razor), if I write the following code

@foreach (var article in Model.Articles)
{
if (article is StandardPage)
        {
var articlePage = article as StandardPage;

If the object inside the article var is of type StandardPage, ArticlePage or news page then the articlePage var will be populated without any issues because StandardPage is the BASE class which ArticlePage & NewsPage both inherit from, however if I change the code to the following

@foreach (var article in Model.Articles)
{
if (article is StandardPage)
        {
var articlePage = article as ArticlePage;

When the object inside the article var is of type StandardPage I will receive an ‘Object reference not set to an instance of an object’ when trying to populate the articlePage var because StandardPage does not inherit from an ArticlePage (it’s the other way around) and therefore I can’t cast something of type StandardPage into and ArticlePage.

Fingers crossed im nearly there with understanding this but if im way off the mark could someone please point me in the right direction

Thanks in advance

Upvotes: 1

Views: 3880

Answers (2)

lyz
lyz

Reputation: 548

I think the notion of base class is relative, a class is base class for the classes which inherits from it, so in your example StandardPage is a base class for ArtcilePage and ArticlePage is also a base class for NewsPage. If you say there is only one base class then the only base class should be Object because all classes inherits from it in the chain.

For the second point, you can not cast an instance of base class to a subclass but you can cast a subclass to a base class, in your example :
NewsPage can be cast to ArticlePage and StandardPage and Object too
AriclePage can be cast to StandardPage and to Object
StandardPage can be cast to Object only

var news = new NewsPage();
var article = new ArticlePage();
var standard = new StandardPage();

news as ArticlePage // works
news as StandardPage // works
news as object // works

article as StandardPage // works
article as object // works
article as NewsPage // won't work

standard as object // works
standard as AriclePages // won't work
standard as NewsPage // won't work

If you could cast base class to subclass then you would be able to cast any class to any other class, because you can cast any class (let's say A)to object as object is base class for all classes and then you cast object to B even if A and B has no reltationship between them.

Upvotes: 1

Paddy
Paddy

Reputation: 33857

What you have stated is pretty much correct, however the nomenclature you are trying to use is a bit confusing.

Stating that ArticlePage is a 'base class' is not overly helpful, it's just a class, it is possibly more useful to state that NewsPage 'is a' ArticlePage (and 'is also' a StandardPage).

If you are casting in your view, you are possibly doing something wrong in your build up of your model. Typically, for inheritance like you have above, you might pass a list of 'StandardPage' objects to your view, where they can all be treated the same for display, however if you are having to cast in your view, you may need to re-examine your architecture, to see if you are really getting the benefit from what you have in place.

For example, if you had the following structure:

Public class StandardPage {
    public virtual string Title() { return "A standard page"; }
}

Public class ArticlePage : StandardPage {
    public override string Title() { return "An article page"; }
}

Public class NewsPage : ArticlePage {
    public override string Title() { return "A news page"; }
}

And your view looked like this, then this might make sense (no casting involved and allows for easy adding of new 'StandardPage' types without requiring changes to your front end):

@foreach (var article in Model.Articles)
{
    <h2>@article.Title()</h2>
}

Upvotes: 1

Related Questions