小编WCW*_*din的帖子

如何避免从基础构造函数调用Viritual方法

我在库中有一个抽象类.我正在尝试尽可能简单地正确实现此类的派生.问题是我需要在三个步骤中初始化对象:获取文件,执行一些中间步骤,然后使用该文件.第一步和最后一步特别适用于派生类.这是一个精简的例子.

abstract class Base
{
    // grabs a resource file specified by the implementing class
    protected abstract void InitilaizationStep1();

    // performs some simple-but-subtle boilerplate stuff
    private void InitilaizationStep2() { return; }

    // works with the resource file
    protected abstract void InitilaizationStep3();

    protected Base()
    {
        InitilaizationStep1();
        InitilaizationStep2();
        InitilaizationStep3();
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,麻烦在于构造函数中的虚方法调用.如果他们不能指望派生类完全初始化,我担心库的使用者在使用类时会发现自己受到限制.

我可以将构造函数中的逻辑拉出到受保护的Initialize()方法中,但是实现者可以直接调用Step1()Step3()不是调用Initialize().问题的关键在于如果Step2()被跳过则不会有明显的错误; 在某些情况下表现糟糕.

我觉得无论哪种方式都存在严重且不明显的"问题",未来的图书馆用户将不得不解决这些问题.我应该使用其他一些设计来实现这种初始化吗?

如有必要,我可以提供更多细节; 我只是想提供表达问题的最简单的例子.

c# inheritance constructor virtual-functions

9
推荐指数
2
解决办法
1753
查看次数

困难的时态跨表数据库约束

我有一个特别困难的业务约束,我想在数据库级别强制执行.这些数据本质上属于财务数据,因此必须保护其不存在与第n度的不一致 - 不要信任业务层.我稍微松散地使用"时间"这个词,这意味着我打算控制一个实体如何能够随着时间而改变.

对细节进行着色,这是设计:

  • 发票可以收取几笔费用.
  • 在创建发票后不久,费用将分配给发票.
  • 发票到达流程中的一个阶段,然后"锁定".
  • 从现在开始,不会向此发票添加或删除任何费用.

这是一个精简的数据定义:

CREATE TABLE Invoices
(
    InvoiceID INT IDENTITY(1,1) PRIMARY KEY,
)

CREATE TABLE Fees
(
    FeeID INT IDENTITY(1,1) PRIMARY KEY,
    InvoiceID INT REFERENCES Invoices(InvoiceID),
    Amount MONEY
)
Run Code Online (Sandbox Code Playgroud)

您会注意到发票的"可锁定"性质未在此处表示; 如何表达它 - 以及它是否需要直接表示 - 仍然是一个悬而未决的问题.

我开始相信这是那些无法转换为域密钥正常形式的安排之一,尽管我可能错了.(毕竟,真的没有办法说出来.)尽管如此,我仍然对高度规范化的解决方案抱有希望.

我碰巧在SQL Server 2008上实现了这个(语法可能是一个暗示),但我是一个好奇的人,所以如果有其他DBMS的解​​决方案,我也很想听到这些.

sql-server constraints crosstab database-agnostic temporal

1
推荐指数
1
解决办法
983
查看次数