-2

I am trying to make a library for MigraDoc, based on this example, which supports different types of documents. My idea was to make a base class, with a virtual method for CreatePage() (the method responsible for the page layout). However, the concept was that CreatePage() should be called from a method called CreateDocument() which is called by the user. Alas, it will be possible to override CreatePage(), but it is not meant to be called directly. It will look something like this:

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...
}

But if create inherited class, which overrides CreatePage(), then which method will be called from CreateDocument()?

  • The original virtual (non-overridden) method
  • The method which overrides CreatePage()
Jakob Busk Sørensen
  • 5,599
  • 7
  • 44
  • 96
  • 1
    The override will be called. – ProgrammingLlama Jun 20 '18 at 08:18
  • if you are then creating an instance of Derived classes and calling CreateDocument, it will call overridden method only – Amit Jun 20 '18 at 08:21
  • 1
    if you don't mean to call `CreatePage()` directly from another code you can user `protected` modifier – rum Jun 20 '18 at 08:21
  • That´s the whole point of `ovderride`, to be able to overwrite the base-implementation. Aynway you could simply try it out yourself by writing a test-program with some virtual member and by checking which member is called, when you override it in your class. – MakePeaceGreatAgain Jun 20 '18 at 08:27
  • for this kind of approach make use of template design pattern with abstract class where method will remain abstract – Pranay Rana Jun 20 '18 at 09:06
  • @PranayRana that is actually what I ended up doing. So I am happy to see it suggested by someone else :-). – Jakob Busk Sørensen Jun 20 '18 at 10:18
  • @Noceo - i was about to answer but then i see you accepted answer and happy with it so not answered – Pranay Rana Jun 20 '18 at 10:24

1 Answers1

5

Since the method is virtual, the correct version will be called. The mechanism at work is called polymorphism.

In fact CreateDocument does not even need to be virtual for this to work (unless you intend to override it in another base class).

You can see it at work with a simple test program (note that I made CreatePage protected so it cannot be called from outside DocumentWriter or its base classes). Note that even when I am calling CreateDocument explicitly through the base class type, it will always call the correct version based on the run-time type of the object.

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();
    }
}

This prints

PdfDocumentWriter.CreatePage()
HtmlDocumentWriter.CreatePage()

as expected.

CompuChip
  • 9,143
  • 4
  • 24
  • 48
  • Thank you for very understandable answer. I will make the base function non-virtual (since this should not be overridden) and only allow overriding the sub-methods. – Jakob Busk Sørensen Jun 20 '18 at 08:27