2016-09-18 40 views
1

我使用Delphi`s記錄,我寫了一個構造它如何防止隱式初始化德爾福

TNullableDateTime = record 
    IsNull: Boolean; 
    Value: TDateTime; 
    constructor Create(IsNull: Boolean; Value: TDateTime) 
end; 

的問題是,我想阻止隱式創建這種類型的記錄,如:

有沒有辦法做到這一點?

+0

查看[A「Nullable」Post by Allen Bauer](http:///community.embarcadero.com/blogs/entry/a-andquotnullableandquot-post-38869)你會發現你的問題的解決方案 - 那就是創建空的記錄。 –

+1

我建議使用[Spring4D Nullable ](https://bitbucket.org/sglienke/spring4d/src/6ce84d716e33be33c2914319ec7d143d5fb2adc4/Source/Base/Spring.pas?at=master#Spring.pas-308) –

回答

2

唯一的你可以做什麼:作出這樣

TNullableDateTime = record 
private 
    IsNull: Boolean; 
    Value: TDateTime; 
public 
    constructor Create(IsNull: Boolean; Value: TDateTime); 
    function getValue : TDateTime; 
    function getIsNull : boolean; 
end; 

所以,你必須添加setter和getter方法適合於您的會員數據的私有性。 你也可以只讀屬性

+0

這不會強制用戶調用構造函數,並且這些值沒有初始化 –

+0

@DavidHeffernan你說得對,唯一的是,你可以防止使用經典記錄 – Fritzw

+0

但是你建議不強制初始化。這裏沒有什麼改變有問題的代碼的行爲。 –

3

它不能做到。如果你想強迫成員使用構造函數進行初始化,你需要一個引用類型(一個類)。

+0

我看到...我想避免這種開銷。 – itay312

+0

在這種情況下,我會建議你忽略任何建議,添加託管類型到你的類型。正如Uwe建議的那樣。這樣做只會給你一種充滿分心的類型。我的建議是,你要確保你總是初始化你的類型。 Onus回程序員。 –

2

正如David所說,你不能強制使用創建在編譯時(甚至沒有帶班),但你可以在運行時,當有人觸及的屬性,而無需調用之前創建引發異常。此代碼將字段更改爲屬性,並利用事實,即記錄中的字符串字段被初始化爲空字符串:

type 
    TNullableDateTime = record 
    private 
    FIsNull: Boolean; 
    FSentinel: string; 
    FValue: TDateTime; 
    procedure CheckSentinel; 
    function GetIsNull: Boolean; 
    function GetValue: TDateTime; 
    procedure SetIsNull(const AValue: Boolean); 
    procedure SetValue(const AValue: TDateTime); 
    public 
    constructor Create(AIsNull: Boolean; const AValue: TDateTime); 
    property IsNull: Boolean read GetIsNull write SetIsNull; 
    property Value: TDateTime read GetValue write SetValue; 
    end; 

constructor TNullableDateTime.Create(AIsNull: Boolean; const AValue: TDateTime); 
begin 
    FSentinel := '*'; 
    FValue := AValue; 
    FIsNull := AIsNull; 
end; 

procedure TNullableDateTime.CheckSentinel; 
begin 
    if FSentinel = '' then 
    raise Exception.Create('please use TNullableDateTime.Create!'); 
end; 

function TNullableDateTime.GetIsNull: Boolean; 
begin 
    CheckSentinel; 
    Result := FIsNull; 
end; 

function TNullableDateTime.GetValue: TDateTime; 
begin 
    CheckSentinel; 
    Result := FValue; 
end; 

procedure TNullableDateTime.SetIsNull(const AValue: Boolean); 
begin 
    CheckSentinel; 
    FIsNull := AValue; 
end; 

procedure TNullableDateTime.SetValue(const AValue: TDateTime); 
begin 
    CheckSentinel; 
    FValue := AValue; 
end;