为什么我的隐藏方法会被Viewbag中的对象覆盖

本文关键字:对象 覆盖 Viewbag 我的 隐藏 方法 为什么 | 更新日期: 2023-09-27 18:24:39

我正在使用VSExpress for Web。

public class BaseClass
{
    public virtual String Method1()
    {
        return "Base class overridable Method 1";
    }
    public String Method2()
    {
        return "Base class hideable Method 2";
    }
}
public class DerivedClass : BaseClass
{
    public override String Method1()
    {
        return "Derived class overriden Method 1";
    }
    public new String Method2()
    {
        return "Derived class hidden  Method 2";
    }
}

当方法2在控制器中运行时

public class HomeController : Controller
{
    // GET: Home
    public String Index()
    {
        BaseClass isDefinitelyBase = new BaseClass();
        BaseClass isReallyChild = new DerivedClass();
        DerivedClass isDefinitelyChild = new DerivedClass();
        return isReallyChild.Method2();
    }
}

输出为

"基类隐藏方法2"


当对象被放置在Viewbag中并发送到View时,该方法被覆盖

public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index()
    {
        BaseClass isDefinitelyBase = new BaseClass();
        BaseClass isReallyChild = new DerivedClass();
        DerivedClass isDefinitelyChild = new DerivedClass();
        ViewBag.ReallyChild = isReallyChild;
        return View();
    }

index.cshtml

@ViewBag.ReallyChild.Method2();

输出为:

"派生类隐藏方法2"

为什么我的隐藏方法会被Viewbag中的对象覆盖

这里的原因是ViewBag是一个动态变量,它只知道实际类型是什么,不知道您是从基类型分配的。

因此,在视图中,它只知道它是派生类型,除非您将其显式转换为基类型,这将为您提供基隐藏方法。顺便说一句,这并没有被"覆盖"。Overriden意味着它是虚拟的,并且作为基类型调用基会得到派生类型。事实并非如此。。您将实例作为派生类型调用,因为dynamic不知道有什么不同。

更改

BaseClass isReallyChild = new DerivedClass();

var isReallyChild = new DerivedClass();

ViewBag在运行时设置类型,而不是在编译时设置类型。获得基类方法的原因是该类型仍然是基类。

要从ViewBag获得基础,请尝试:

var base = (BaseClass)ViewBag.ReallyChild;
var res = base.Method2();