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

El *_*blo 2 delphi default numbers properties

当我安装组件时,我查看了对象检查器,其值为StoppingCount0!我需要值为-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;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 9

负值工作得很好。问题是您实际上并没有初始化FStoppingCount为 -1,因此当组件的新实例被创建并且它们的内存最初被清零时,它反而被初始化为 0。

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

属性 (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;
Run Code Online (Sandbox Code Playgroud)