通过强制转换 (ChildClass)parentObject 调用子构造函数;跟踪修订
为了跟踪 Page
类的修订,我有一个 PageRevision
类,它继承自 Page
并添加修订 ID (Guid RevisionID; )。
如果可能,我应该如何将现有的 Page
对象转换为 PageRevision
并确保调用 PageRevision 构造函数来创建新的修订 ID?
我可以有一个 PageRevision(Page page)
构造函数来生成 Guid 并复制所有 Page 属性,但我想自动化它,特别是如果 Page
类有很多属性(后来我添加了一个,并且忘记修改复制构造函数)。
所需使用
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
类:
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();
}
}
根据反馈进行编辑:
除了现在显而易见的 (Horse)Animal;
选角问题,Jon Skeet 还建议复合修订版:
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;
}
}
但是,这与我的数据模型有很大不同,我希望保持两者尽可能相似。在我的数据库中,PageRevisions
表与 Pages
表具有相同的列,但有一个额外的 RevisionID
列。使用数据库触发器可以轻松进行版本控制。
- 鉴于这种复合方法,使用
PageRevisions
来存储所有页面数据是否更有意义:RevisionID
、Title
和 < code>Body,而Pages
表仅存储 URLSlug
和引用PageRevisions< 的
RevisionID
/代码>表?
To track revisions of a Page
class, I have a PageRevision
class which inherits from Page
and adds a revision ID (Guid RevisionID;
).
If possible, how should I cast an existing Page
object to a PageRevision
and ensure that the PageRevision constructor is called to create a new revision ID?
I could could have a PageRevision(Page page)
constructor which generates the Guid and copies all the Page attributes, but I want to automate it, especially if a Page
class has many attributes (and I later add one, and forget to modify 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:
Besides the now-obvious (Horse)Animal;
casting problem, Jon Skeet recommends a composite 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 quite different from my data model and I'd like to keep the two as similar as possible. In my database, the PageRevisions
table has the same columns as the Pages
table, expect for an extra RevisionID
column. This is easy to version with a database trigger.
- In the light of this composite approach, would it make more sense to have a
PageRevisions
to store all page data: aRevisionID
,Title
andBody
, while aPages
table only stores an URLSlug
and aRevisionID
that refers to thePageRevisions
table?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么不让您的 PageRevision 类组合而不是继承?
Why not make your PageRevision class compose instead of inheriting?
你不能。
马是一种动物,但并不是所有的动物都是马。
所以马=>动物是可能的,但动物=>马不。而你正试图将你的动物变成一匹马。
You cannot.
A horse is an animal, but not every animal is a horse.
So horse => animal is possible, but animal => horse not. And you are trying to cast your animal into a horse.
无论您是否将类强制转换为 PageRevision,PageRevision 构造函数始终都会被调用。所以这根本行不通。
告诉你为什么要这样做可能更有意义,因为你这样做的原因很可能可以通过其他方式解决。
The PageRevision constructor ALWAYS gets called regardless if you cast the class to PageRevision or not. So this isn't going to work at all.
It likely makes more sense you tell why you want to do that because you are likely doing that for reasons that are solved in other ways.
在强制转换期间,不会调用构造函数,因为对象已经创建。
尽管您的转换在运行时会失败,因为 Page 无法转换为 PageRevision (也可以采用其他方式)
在您的情况下,我会将 RevisionId 添加到您的基类 Page。如果您创建一个 Page 对象,则可以使用 Guid.Empty 创建它。派生类可以使用基类 Page 的构造函数设置 RevisionId。
During a cast, there is no constructor called, because the object is already created.
Although your cast will fail at runtime, cause Page cannot be cast to PageRevision (the other way is possible)
In your case i would add the RevisionId to your base class Page. If you create a Page object it could be created with Guid.Empty. Derived classes could set the RevisionId using an constructor of your base class Page.