如何防止Delphi中的隐式初始化

时间:2016-09-18 14:38:44

标签: delphi

我正在使用Delphi的记录,我为它编写了一个构造函数

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

问题是我想要阻止创建这种类型的记录,如:

SomeNullableDateTime: TNullableDateTime;
SomeNullableDateTime.IsNull:= True; 

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:3)

无法完成。如果要强制使用构造函数初始化成员,则需要引用类型(类)。

答案 1 :(得分:2)

唯一可以做的事情:使成员数据像

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

所以你必须为你的类型添加setter和getter。 您也可以执行只读属性

答案 2 :(得分:2)

正如David所说,你不能在编译时强制使用 Create (即使不是类),但是当有人触摸属性而不调用时,你可以在运行时引发异常之前创建。此代码将字段更改为属性,并利用事实,记录中的字符串字段初始化为空字符串:

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;
相关问题