关于c#:从base调用虚方法

Calling virtual method from base

本问题已经有最佳答案,请猛点这里访问。

我正试图根据这个例子为migradoc创建一个库,它支持不同类型的文档。我的想法是用CreatePage()的虚拟方法(负责页面布局的方法)创建一个基类。但是,概念是,应该从一个名为CreateDocument()的方法调用CreatePage(),该方法由用户调用。唉,可能会覆盖CreatePage(),但并不打算直接调用它。它看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DocumentWriter
{
    private Document document;

    public virtual void CreateDocument(IDocumentArgs args)
    {
       document = new Document();

       DefineStyles();
       CreatePage();
       FillContent(args);
    }

    public virtual void CreatePage()
    {
        // Create page layout here
    }

    // Remaining code skipped for readability...
}

但是,如果创建继承类(它重写CreatePage()),那么将从CreateDocument()调用哪个方法?

  • 原始虚拟(非重写)方法
  • 覆盖CreatePage()的方法


由于方法是virtual,因此将调用正确的版本。这种机制被称为多态性。

实际上,CreateDocument甚至不需要是虚拟的就可以工作(除非您打算在另一个基类中重写它)。

您可以看到它与一个简单的测试程序一起工作(注意,我制作了CreatePageprotected,因此它不能从DocumentWriter或其基类外部调用)。注意,即使我通过基类类型显式地调用CreateDocument时,它也总是基于对象的运行时类型调用正确的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class DocumentWriter
{
    public /*virtual*/ void CreateDocument()
    {
       CreatePage();
    }

    protected virtual void CreatePage()
    {
        System.Console.WriteLine("DocumentWriter.CreatePage()");
    }
}

public class PdfDocumentWriter : DocumentWriter
{
    protected override void CreatePage()
    {
        System.Console.WriteLine("PdfDocumentWriter.CreatePage()");
    }
}

public class HtmlDocumentWriter : DocumentWriter
{
    protected override void CreatePage()
    {
        System.Console.WriteLine("HtmlDocumentWriter.CreatePage()");
    }
}

public static class Program
{
    public static void Main()
    {
        DocumentWriter documentWriter = new PdfDocumentWriter();
        documentWriter.CreateDocument();

        // Re-use the same variable.
        // CreateDocumentwill still call the correct version of CreatePage.
        documentWriter = new HtmlDocumentWriter();
        documentWriter.CreateDocument();
    }
}

这张照片

1
2
PdfDocumentWriter.CreatePage()
HtmlDocumentWriter.CreatePage()

果不其然。