【问题标题】:function overrides not calling函数覆盖不调用
【发布时间】:2013-04-15 11:48:40
【问题描述】:

我正在编写的程序出现问题,我的虚拟函数似乎没有按应有的方式运行。

我有一个带有虚函数的类,以及一个覆盖它的派生类。当我调用该函数时,不会调用覆盖,但会调用基础。这是我之前做过一百万次的事情,但我不知道这种行为在简单的情况下是如何破坏的。

举个例子:

public class ClassA
{
  public DoStuff()
  {
    MyVirtual()
  }

  protected virtual MyVirtual()
  {
    Console.WriteLine("Base MyVirtual Called");
  }
}

public class ClassB : ClassA
{
  protected override MyVirtual()
  {
    Console.WriteLine("Overridden MyVirtual Called");
  }
}

ClassA test = new ClassB;
test.DoStuff();

这个例子只是为了效果(我没有编译它来检查它,我只是演示)。我只想知道什么会破坏它,所以不会调用覆盖。我不能粘贴我的具体代码,但理论上就是这么简单。

  • 继承层次结构只有两个类
  • 没有密封的修饰符
  • 类是通过对继承类的简单调用 new 来创建的
  • 虚函数受到保护,并像这样从基类中的公共函数调用

这怎么可能破坏或者什么会干扰这种行为?该项目非常复杂,但这并不是我正在实施的新事物。在我的特定代码中,甚至还有另一个以完全相同的方式编写并以相同方式继承的虚函数,效果很好。我什至通过复制/粘贴该函数并重命名来创建新函数,因此语法应该相同(当它们不起作用时我确实从头开始重建它们,但它们的行为没有区别)。

无论如何,我已经束手无策了,我不能花几天时间为此寻找一个晦涩难懂的原因,所以任何关于从哪里开始寻找的想法都将不胜感激。

【问题讨论】:

  • 没有什么不能破坏它 - 您在示例中显示的方式。我敢打赌,您的示例并不代表您遇到的真正问题。很可能您的方法不是虚拟的,或者派生版本缺少“覆盖”或类似的东西。由于示例与真实代码无关,您实际上是在让我们猜测为什么我们从未见过的某些代码不起作用
  • 减少你的非工作代码,直到你有一些可以分享的代码。是否正在编译所有内容,例如基类是否在单独的项目中?第二个项目中有另一个类,第三个项目中有你的派生类吗?任何函数修饰符更改都需要重新编译所有三个。我并不是说这是你的问题,但如果没有更多信息,我们无法猜测,更重要的是代码不起作用,可能会发生大量事情。附:我保证,如果您尝试减少代码以制作可共享的示例,那么您会发现问题。所以去做吧!
  • 写得不好的例子。 DoStuff() 既不是构造函数,也没有返回类型。
  • 您是否 100% 确定派生类具有该方法的 virtual 关键字,并且该方法没有被隐藏/隐藏,这意味着始终调用基方法?除非我忘记覆盖,否则我从未经历过这样的事情,但编译器应该警告这一点。
  • 我敢打赌派生类中没有override,但示例中另有说明

标签: c# virtual


【解决方案1】:

如果您修复错误,它会成功编译并按您预期的方式运行。

固定版本:

public class ClassA
{
  public void DoStuff()
  {
    MyVirtual();
  }

  protected virtual void MyVirtual()
  {
    Console.WriteLine("Base MyVirtual Called");
  }
}

public class ClassB : ClassA
{
  protected override void MyVirtual()
  {
    Console.WriteLine("Overridden MyVirtual Called");
  }
}

ClassA test = new ClassB();
test.DoStuff();

输出:

Overridden MyVirtual Called

这基本上意味着,与您的陈述相反,您的代码“理论上没有那么简单”,我的猜测是 您实际上并没有在 B 类中覆盖

【讨论】:

  • 好的。如前所述,该示例只是为了显示问题而我没有编译它(所以如果我有这些错误,我会发现这些错误,并且它们不存在于我正在处理的项目中)。我已经找到了问题所在,这是我自己的愚蠢和睡眠不足。它与虚拟函数无关,但在我的项目中,有一个布尔值检查是否甚至调用该函数,并且复制粘贴是一个静态布尔值,而我没有注意到。多一点挖掘,我会意识到这一点,而不是发布一个愚蠢的问题。对不起。
  • “写得非常糟糕”您唯一更改的是将“受保护的虚拟”更改为“受保护的虚拟空白”,并且添加了一个缺少的分号。理性的人会注意到诸如“ClassA、ClassB、DoStuff”之类的名称,并意识到 OP 没有复制/粘贴代码,而且显然只是有一些拼写错误。
  • @MEE 你是对的。我向 SurvivalistDev 和你们所有人道歉。我确实夸大了和粗鲁。老实说,我不知道我是否在床的错误一侧醒来,但这不是借口。对不起。
【解决方案2】:

如果您在继承链中有多个类,您可能需要检查这些类中具有相同名称的所有方法(如果存在)是否具有“覆盖”

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 2021-04-17
    • 2010-10-11
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多