【问题标题】:How to call the base class method?如何调用基类方法?
【发布时间】:2018-03-14 05:57:21
【问题描述】:

我们有以下代码:

  public class A
  {
    protected virtual void Method()
    {
      Console.Write("A");
    }
  }

  public class B : A
  {
    protected override void Method()
    {
      Console.Write("B");
    }
  }

  public class C : B
  {
    public void Some()
    {
      //How to call Method() from class A?
    }
  }

如何在C类的Some()方法中从A类调用Method()

我们假设 A 和 B 是库中的类,我们无法更改它们。

解决方案:https://stackoverflow.com/a/438952/8081796

【问题讨论】:

  • 我认为除了方法隐藏之外还有其他方法
  • 在对“库”一无所知的情况下 - 看起来您应该从 A 而不是 B 派生。如果该类的其余部分应以“B”方式运行,则可以使用组合和代理除此之外的所有方法都指向 B 的内部实例。(“内部”与“私有”中的一样)但实际上:对我来说,这看起来像是一个设计审查案例。

标签: c# oop


【解决方案1】:

B 覆盖 Method()A 将其标记为虚拟和受保护,调用它的唯一方法(以其当前格式)是 B 以某种方式调用它

public class B : A 
{
   protected override void Method()
   {
      base.Method();
      Console.Write("B");
   }
}

或者直接派生自A

public class C : A
{
   public void Some()
   {
      Method();
   }
}

virtual (C# Reference) | Microsoft Docs

virtual 关键字用于修改方法、属性、索引器或 事件声明并允许它在派生中被覆盖 班级。例如,这个方法可以被任何类覆盖 继承它:

此外

当调用虚方法时,对象的运行时类型为 检查覆盖成员。最重要的成员 派生类被调用,它可能是原始成员,如果没有 派生类已覆盖该成员。

protected (C# Reference)

受保护的成员可以在其类中访问,也可以通过派生类访问 实例。

【讨论】:

  • 我们假设 A 和 B 是库中的类,我们无法更改它们。
  • 原来这是不可能的?
  • @StepanIvanenko 确实是的,除非您可以更改课程或更改您的要求
【解决方案2】:

如果您 really 希望在此处调用 AMethod(不更改 ABMethod 的实现),则必须进行以下更改。

  1. B 类的Method 的访问说明符从override 更改为new

    override 将覆盖基类方法。让它new 不会这样做。

  2. ABMethods 的访问说明符更改为public 而不是protected

    Aprotected 成员将无法在您的C 类中访问。

进行此更改后,请查看以下代码。您将看到 A 类中的 Method 被调用。

static void Main()
{
    var c = new C();
    c.Some();
    Console.ReadKey();
}
public class A
{
    public virtual void Method()
    {
        Console.Write("A");
    }
}

public class B : A
{
    public new void Method()
    {
        Console.Write("B");
    }
}

public class C : B
{
    public void Some()
    {
        //How to call Method() from class A?
        ((A)this).Method();
    }
}

如果你不能进行上述的改变,那恐怕你不能打电话给AMethod:O。

【讨论】:

  • 我们假设 A 和 B 是库中的类,我们无法更改它们。
  • ((A)this).Method(); 未编译 :)
  • 你复制了我的完整代码吗?您一定错过了更改 1 和 2。它适用于 .Net 4.6.1。你用的是哪个编译器?
  • Paritosh Maharaj、class Aclass B 是库类,我们无法更改它们。
  • @StepanIvanenko - 这就是我在最后一行和最后一条评论中所写的内容。
【解决方案3】:

这是不可能的,因为

虚拟成员的实现可以通过重写来改变 派生类中的成员。

B 更改了A 的实现,因此C 仅将B 实现为base 而没有实现A

解决方案:https://stackoverflow.com/a/438952/8081796

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-13
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多