通过强制转换 (ChildClass)parentObject 调用子构造函数;跟踪修订

发布于 2024-08-29 23:55:36 字数 1811 浏览 7 评论 0原文

为了跟踪 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.

PagePageRevision 类:

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 来存储所有页面数据是否更有意义:RevisionIDTitle 和 < code>Body,而 Pages 表仅存储 URL Slug 和引用 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: a RevisionID, Title and Body, while a Pages table only stores an URL Slug and a RevisionID that refers to the PageRevisions table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

依 靠 2024-09-05 23:55:36

为什么不让您的 PageRevision 类组合而不是继承?

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

Why not make your PageRevision class compose 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;
    }
}
擦肩而过的背影 2024-09-05 23:55:36

你不能。

马是一种动物,但并不是所有的动物都是马。

所以马=>动物是可能的,但动物=>马不。而你正试图将你的动物变成一匹马。

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.

自找没趣 2024-09-05 23:55:36

无论您是否将类强制转换为 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.

生生不灭 2024-09-05 23:55:36

在强制转换期间,不会调用构造函数,因为对象已经创建。

尽管您的转换在运行时会失败,因为 Page 无法转换为 PageRevision (也可以采用其他方式)

在您的情况下,我会将 RevisionId 添加到您的基类 Page。如果您创建一个 Page 对象,则可以使用 Guid.Empty 创建它。派生类可以使用基类 Page 的构造函数设置 RevisionId。

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()) {

    }
}

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.

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()) {

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文