负属性默认值似乎不起作用

时间:2019-12-21 17:23:03

标签: delphi properties numbers default

安装组件时,我在对象检查器中查看,StoppingCount的值为0!我需要将值设为-1。在我的代码中,任何高于-1的值都会在该数字处停止for循环过程。

default是否不能用于负数?

unit myUnit;

interface

uses
  System.SysUtils, System.Classes;

type
  TmyComponent = class(TComponent)
  private
    { Private declarations }
    FStoppingCount: integer;

  protected
    { Protected declarations }
    procedure ProcessIT();

  public
    { Public declarations }

  published
    { Published declarations }

    property StoppingCount: integer read FStoppingCount write FStoppingCount default -1;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('myComponent', [TmyComponent]);
end;

procedure TmyComponent.ProcessIT();
begin
  for I := 0 to 1000 do
  begin
    DoSomething();
    if FStoppingCount = I then break;
  end;
end;

1 个答案:

答案 0 :(得分:9)

负值可以正常工作。问题是您实际上没有将FStoppingCount初始化为-1,因此当创建组件的新实例并将其内存初始清零时,它会初始化为0。

仅在default声明中声明非零的property值是不够的。 default值仅存储在属性的RTTI中,并且仅在将组件写入DFM以及在对象检查器中显示属性值时用于比较目的。 default指令实际上并不影响内存中组件的实例。您必须显式设置FStoppingCount的值以匹配default的值。文档中明确说明了这一点:

Properties (Delphi)

  

注意:属性值不会自动初始化为默认值。也就是说,默认伪指令仅控制何时将属性值保存到表单文件中,而不控制新创建实例上属性的初始值。

要修复组件,您需要添加一个将FStoppingCount初始化为-1的构造函数,例如:

unit myUnit;

interface

uses
  System.SysUtils, System.Classes;

type
  TmyComponent = class(TComponent)
  private
    { Private declarations }
    FStoppingCount: integer;
  protected
    { Protected declarations }
    procedure ProcessIT();
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override; // <-- ADD THIS!
  published
    { Published declarations }
    property StoppingCount: integer read FStoppingCount write FStoppingCount default -1;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('myComponent', [TmyComponent]);
end;

constructor TmyComponent.Create(AOwner: TComponent);
begin
  inherited;
  FStoppingCount := -1; // <-- ADD THIS!
end;

procedure TmyComponent.ProcessIT();
begin
  for I := 0 to 1000 do
  begin
    DoSomething();
    if FStoppingCount = I then break;
  end;
end;