2

Pageクラスのリビジョンを追跡するために、リビジョン ID ( )PageRevisionを継承しPageて追加するクラスがありますGuid RevisionID;

可能であれば、既存のPageオブジェクトをにキャストPageRevisionし、PageRevision コンストラクターを呼び出して新しいリビジョン ID を作成するにはどうすればよいですか?

Guid を生成し、すべての Page 属性をコピーするコンストラクターを使用することもできますがPageRevision(Page 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;
    }
}

ただし、これは私のデータ モデルとはかなり異なるため、この 2 つをできるだけ似たものにしたいと考えています。私のデータベースでは、PageRevisionsテーブルにはテーブルと同じ列がありPages、余分なRevisionID列があることを期待しています。これは、データベース トリガーを使用して簡単にバージョン管理できます。

  • この複合的なアプローチに照らして、PageRevisionsにすべてのページ データ ( 、RevisionIDTitleおよび) を格納Bodyし、Pagesテーブルには URLSlugRevisionIDそのテーブルを参照するのみを格納する方が理にかなっているPageRevisionsでしょうか?
4

4 に答える 4

5

継承する代わりに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;
    }
}
于 2010-04-23T11:18:16.807 に答える
1

クラスをPageRevisionにキャストするかどうかに関係なく、PageRevisionコンストラクターは常に呼び出されます。したがって、これはまったく機能しません。

他の方法で解決される理由でそうしている可能性が高いので、なぜそれをしたいのかを伝える方が理にかなっているでしょう。

于 2010-04-23T11:21:37.717 に答える
1

オブジェクトがすでに作成されているため、キャスト中に呼び出されるコンストラクターはありません。

キャストは実行時に失敗しますが、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()) {

    }
}
于 2010-04-23T11:18:31.687 に答える
1

それはいけません。

馬は動物ですが、すべての動物が馬というわけではありません。

したがって、馬 => 動物は可能ですが、動物 => 馬はできません。そして、あなたは自分の動物を馬に投げ込もうとしています。

于 2010-04-23T11:18:38.027 に答える