ASP.NET MVC 中的继承和 BASE 类

本文关键字:BASE 继承 NET MVC ASP | 更新日期: 2023-09-27 18:31:21

我正在尝试了解MVC应用程序中的继承,如果有人可以提供帮助,我想澄清几件事。

问题1

如果我有以下三个类,它们相互继承,如下所示

Public class StandardPage
Public class ArticlePage : StandardPage
Public class NewsPage : ArticlePage

StandardPage 类是这里唯一的 BASE 类,还是 ArticlePage 类也称为 BASE 类,因为 NewsPage 类派生自它?

简而言之,从其他类派生的类是否也称为 BASE 类(对于继承它的类)?

问题2

如果我在强类型视图文件(使用 Razor)中工作时定义了上述类,如果我编写以下代码

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

如果文章 var 中的对象是 StandardPage、ArticlePage 或新闻页面的类型,那么 articlePage var 将被填充而没有任何问题,因为 StandardPage 是 ArticlePage 和 NewsPage 都继承的 BASE 类,但是如果我将代码更改为以下内容

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

当文章变量中的对象类型为 StandardPage 时,在尝试填充 articlePage var 时,我将收到"对象引用未设置为对象的实例",因为 StandardPage 不是从 ArticlePage 继承的(相反),因此我无法将 StandardPage 类型的内容转换为 ArticlePage 和 ArticlePage。

手指交叉我几乎在那里理解这一点,但如果我偏离了目标,有人可以指出我正确的方向

提前致谢

ASP.NET MVC 中的继承和 BASE 类

我认为基类的概念是相对的,类是继承自它的类的基类,所以在你的例子中,StandardPage是ArtcilePage的基类,ArticlePage也是NewsPage的基类。如果你说只有一个基类,那么唯一的基类应该是 Object,因为链中的所有类都继承自它。

对于第二点,您不能将基类的实例强制转换为子类,但可以将子类强制转换为基类,在您的示例中:
新闻页面也可以投射到文章页面和标准页面和对象
AriclePage可以转换为StandardPage和Object
标准页面只能投射到对象

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
如果可以将基类强制转换为子类,那么您将能够将任何类强制转换为任何其他类,因为

您可以将任何类(假设 A)转换为对象,因为对象是所有类的基类,然后您将对象强制转换为 B,即使 A 和 B 之间没有关系。

您所说的几乎是正确的,但是您尝试使用的命名法有点令人困惑。

声明 ArticlePage 是一个"基类"并

不过分有用,它只是一个类,声明 NewsPage "是一个"ArticlePage(并且"也是"一个标准页面)可能更有用。

如果你在你的视图中投射,你可能在构建你的模型时做错了什么。 通常,对于上述继承,您可以将"StandardPage"对象列表传递给您的视图,在视图中可以将它们都视为相同的显示,但是,如果您必须在视图中投射,则可能需要重新检查您的体系结构,以查看您是否真的从现有内容中受益。

例如,如果您有以下结构:

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"; }
}

您的视图如下所示,那么这可能是有意义的(不涉及强制转换,并且允许轻松添加新的"StandardPage"类型,而无需更改前端):

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