2

当你重写一个方法时,你不应该改变方法的行为,你只是专门化它。因此,您必须调用base.MyVirtualMethod()被覆盖的方法并添加专门化代码。

但我总是想知道什么时候必须调用base.MyVirtualMethod(). 或者从另一个角度来看,我如何编写我的虚拟方法?我应该期望用户将其称为被覆盖方法所做的第一件事还是最后一件事?

public class Parent
{
    public virtual void MyMethod(){ /* Some code*/ }
}
public class Child : Parent
{
    public override void MyMethod()
    {
        /* Does my code goes here? */
        base.MyMethod();
        /* Or does my code goes here? */
    }
}
4

6 回答 6

4

因此,您必须在覆盖的方法中调用 base.MyVirtualMethod() 并添加专门化代码。

这并不总是正确的——在某些情况下,您不想在派生类中执行超类正在执行的操作,因此您不想调用base.

如果您想扩展基本行为,您可以在base调用之前或之后放置代码,具体取决于实际问题。没有规则“总是在你的代码之前调用 base”。

于 2011-11-25T11:16:18.507 回答
2

碱基调用不必存在。您可以在文档中指定基本调用是否应该在其他代码之前、在其他代码之后、两者都或都不(不存在),以及其他代码的确切性质应该是什么。这一切都取决于您要完成的工作。

如果您发现附加代码的最佳位置确实是基本调用内部的某个地方,那么这意味着应该将基本方法拆分为两个或多个方法。

于 2012-01-03T15:04:29.070 回答
1

与许多问题一样,答案是“视情况而定”。

假设您正在扩展将一些数据写入文件的类,并且扩展需要在文件末尾添加更多数据(SimpleDataFile.writeFile()extended by ExtendedDataFile.writeFile()):在这种情况下,您将在调用 base 之后添加代码方法。

现在,假设您的扩展添加了一个预处理工具,可能会为基本文件输出添加颜色(SimpleDataFile.writeFile()扩展为FancyDataFile.writeFile()):在这种情况下,您实际上会在任何内容发送到文件之前采取行动,并且您的代码将在基本文件之前结束称呼。

于 2011-11-25T11:15:32.970 回答
1

要准确回答您的问题:不要覆盖它:) 当您覆盖它时,您将改变行为。大多数时候,我将新代码放在基方法的调用下方,因为它确实执行了这个基本行为,然后执行了一些额外的行为。但是,这不是一成不变的,实际上取决于您的需求。

于 2011-11-25T11:15:42.110 回答
1

我通常首先调用基本方法,以确保任何所需的初始化已经发生,并且我的代码实际上覆盖了基本行为,而不是相反。显然这取决于具体情况,但很可能在某些情况下您知道您的代码需要首先运行。

于 2011-11-25T11:17:54.007 回答
0

这取决于你想做什么,但两者都可以!

于 2011-11-25T11:16:04.357 回答