Calling the child constructor by casting (ChildClass) parentObject; track changes

To keep track of class changes Page

, I have a class PageRevision

that inherits from Page

and adds a revision id ( Guid RevisionID;

).

If possible, how should I apply the existing object Page

to PageRevision

and make sure the PageRevision constructor is called to create a new revision id?

I could have a constructor PageRevision(Page page)

that generates a Guid and copies all page attributes, but I want to automate it, especially if the class Page

has a lot of attributes (and I add it later and forget to change the copy constructor).

Desired use

Page page = new Page(123, "Page Title", "Page Body"); // where 123 is page ID
PageRevision revision = (PageRevision)page;
// now revision.RevisionID should be a new Guid.

      

Page

, PageRevision

classes:

public class Page
{
    public int ID { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
}

public class PageRevision : Page
{
    public Guid RevisionID { get; set; }

    public PageRevision()
    {
        this.RevisionID = Guid.NewGuid();
    }
}

      

Edit based on feedback:

Apart from the obvious casting issue (Horse)Animal;

, Jon Skeet recommends a complex revision:

public class PageRevision : Page
{
    private readonly Page page;
    private readonly Guid id;
    public Guid RevisionID { get { return id; } }
    public Page Page { get { return page; } }

    public PageRevision(Page page)
    {
        this.id = Guid.NewGuid();
        this.page = page;
    }
}

      

However, this is very different from my data model, and I would like the two to be as similar as possible. In my database, the table PageRevisions

has the same columns as the table Pages

, an extra column is expected RevisionID

. This is easy for the database trigger version.

  • In light of this complex approach, it would make more sense to have PageRevisions

    to store all the page data: a RevisionID

    , Title

    and Body

    , whereas the table Pages

    only stores the URL Slug

    and a RevisionID

    that refers to the table PageRevisions

    ?
+2


a source to share


4 answers


Why not create a PageRevision class instead of inheriting?



public class PageRevision : Page
{
    private readonly Page page;
    private readonly Guid id;
    public Guid RevisionID { get { return id; } }
    public Page Page { get { return page; } }

    public PageRevision(Page page)
    {
        this.id = Guid.NewGuid();
        this.page = page;
    }
}

      

+5


a source


There is no constructor during casting because the object has already been created.

Even though your show will not run at runtime, will not result in the Page not being passed to PageRevision (another way is possible)



In your case, I'll add the RevisionId to the base class page. If you create a page object, it can be created using Guid.Empty. Derived classes can set the RevisionId using your base page constructor.

public class Page {

    public Page() {
        RevisionId = Guid.Empty;
    }

    protected Page(Guid revisionId) {
        RevisionId = revisionId;
    }

    public Guid RevisionId {
        get;
        private set;
    }
}

public class PageRevision : Page {

    public PageRevision()
        : base(Guid.NewGuid()) {

    }
}

      

+1


a source


You can not.

A horse is an animal, but not every animal is a horse.

So horse => animal is possible, but animal => horse is not. And you are trying to transform your animal into a horse.

+1


a source


The PageRevision constructor is ALWAYS called regardless of whether you choose a class for PageRevision or not. So it won't work at all.

Chances are, you understand why you need this, because you are probably doing it for reasons that are addressed in other ways.

+1


a source







All Articles