C#从基类隐藏,覆盖和调用函数

Luk*_*sik 15 c# inheritance overriding base member-hiding

我正在学习C#,我遇到了以下问题.我有两个类:base和derived:

class MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyBase::MyMethod()");
    }
}


class MyDerived: MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyDerived::MyMethod()");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,没有virtualoverride关键词.当我编译它时,我得到警告(当然是预期的)我试图隐藏MyMethodMyBase课堂上.

我想要做的是从具有派生类实例的基类调用该方法.我是这样做的:

MyDerived myDerived = new MyDerived();
((MyBase)myDerived).MyMethod();
Run Code Online (Sandbox Code Playgroud)

当我没有virtual在方法中指定任何等关键字时,它工作正常.我试着把关键字组合起来,得到了以下结果:

| MyBase::MyMethod | MyDerived::MyMethod | Result printed on the console |
| -----------------|---------------------|-------------------------------|
| -                | -                   | MyBase::MyMethod()            |
| -                | new                 | MyBase::MyMethod()            |
| virtual          | new                 | MyBase::MyMethod()            |
| virtual          | override            | MyDerived::MyMethod()         |
Run Code Online (Sandbox Code Playgroud)

我希望你的表格清楚.我有两个问题:

  1. 它是从基类(((MyBase)myDerived).MyMethod();)调用函数的正确方法吗?我知道base关键字,但它只能从派生类的内部调用.这样对吗?
  2. 为什么在最后一种情况下(使用virtualoverride修饰符)被调用的方法来自派生类?你能解释一下吗?

SLa*_*aks 18

当您virtual在覆盖该方法的类型的实例上调用方法时,即使您转换为基类,也将始终调用被覆盖的版本.

在覆盖该方法的类上调用虚方法的基本实现的唯一方法是在派生类(而不是基类)中使用base关键字调用该方法的第二个方法.

一般来说,需要这样做是一个糟糕的API设计的标志 - 如果你认为你需要调用基本版本,派生版本应该有一个不同的名称.

  • +1 - 很好解释.设计讨论的额外要点. (2认同)