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: aRevisionID
,Title
andBody
, whereas the tablePages
only stores the URLSlug
and aRevisionID
that refers to the tablePageRevisions
?
a source to share
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;
}
}
a source to share
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()) {
}
}
a source to share