プロパティ(Property)

本節ではプロパティ(Property)の定義、構文、規約、シリアライズについて学習します

Propertyとは何か

propertyはPascalのシンタックスシュガーです。外部からはフィールドと同じように扱えますが、内部的にはgetterによる読み出し / setterによる書き込みが実行されます。プライベートフィールドのカプセル化、読み書きロジックの統一、副作用の追加に使用します。

  1. 読み書き制御可能プロパティ:代入・値取得時に追加ロジックが自動実行されます(UI再描画、コンポーネント同期、数値検証);
  2. 読み取り専用プロパティ:外部からは読み出しのみ可能で直接代入不可、内部の専用メソッドでデータを変更します。
program Demo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
  SysUtils;

type
  TWebPage = class
  private
    FURL: string;
    FColorRGB: Integer;
    procedure SetColorRGB(const Value: Integer);
  public
    property URL: string read FURL;
    property ColorRGB: Integer read FColorRGB write SetColorRGB;

    procedure Load(const AnURL: string);
    procedure PrintStatus;
  end;

procedure TWebPage.Load(const AnURL: string);
begin
  FURL := AnURL;
  Writeln('Load page: ', AnURL);
end;

procedure TWebPage.SetColorRGB(const Value: Integer);
begin
  if FColorRGB <> Value then
  begin
    FColorRGB := Value;
    Writeln('Color updated, value = ', Value);
    Writeln('Sync component color to ', Value);
  end;
end;

procedure TWebPage.PrintStatus;
begin
  Writeln('==== Page Info ====');
  Writeln('URL(read-only): ', URL);
  Writeln('ColorRGB(rw): ', ColorRGB);
  Writeln('==================');
  Writeln;
end;

var
  Page: TWebPage;
begin
  Page := TWebPage.Create;
  try
    Page.Load('https://www.foxdevelop.com/');
    Page.ColorRGB := 255;
    Page.PrintStatus;

    Page.ColorRGB := 255;
    Page.PrintStatus;

    Page.ColorRGB := 65535;
    Page.PrintStatus;

    // Page.URL := 'test'; // コンパイルエラー、URLは読み取り専用
  finally
    Page.Free;
  end;
  Readln;
end.Code language: HTML, XML (xml)

TWebPageのURLプロパティは読み取り専用で、値を変更するにはLoad手続きを使用します。

FColorRGBプロパティは読み出し可能で、書き込み・変更にはSetColorRGB手続きを利用します。

PrintStatusは通常の手続きで、TWebPageの内部情報を出力するために使用します。

実行結果

Load page: https://www.foxdevelop.com/
Color updated, value = 255
Sync component color to 255
==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 255
==================

==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 255
==================

Color updated, value = 65535
Sync component color to 65535
==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 65535
==================Code language: JavaScript (javascript)

2. プロパティ3要素の宣言ルール

プロパティを宣言するには読み出し指定が必須、書き込み指定はオプションです:

read 読み出し元(2択)

  • プライベートフィールドを直接紐付け(最速、追加関数オーバーヘッドなし)
  • 引数なしgetter関数、戻り値型がプロパティと完全一致

write 書き込み元(オプション、省略時は読み取り専用)2択

  • プライベートフィールドを直接紐付け
  • 単一引数setter関数、引数型がプロパティと完全一致

シリアライズ専用追加修飾子:defaultstored

コンパイラは型の一致を強制的に検証します:

  • Integer型プロパティ:getterは引数なしでIntegerを返す / readにIntegerプライベートフィールドを紐付け
  • String型プロパティ:setterはconst string引数を受け取る必要がある

Publishedプロパティとシリアライズ

1. シリアライズとは

オブジェクトの全データをストリーム(ファイル/メモリ/JSON)に書き出し、後からストリームからオブジェクトを復元する仕組み;

Lazarusフォーム.lfm、Delphi.dfmフォームファイルは内部的にこの機構に完全依存しています。

  • 前提条件:プロパティをpublishedセクションに記述しないとRTTI実行時型情報が認識できない
  • 対応ユニット:
  • LResources:lfmフォームファイルの読み書き
  • FpJsonRtti / CastleComponentSerialize:オブジェクトのJSONシリアライズ

2. シリアライズ専用修飾子

default <定数>:プロパティのデフォルト値を指定

  • シリアライズツールの判定用:オブジェクト生成後の値がdefaultと同じ場合、シリアライズ時に保存を省略しファイルサイズを削減
  • 自動初期化されない:コンストラクタ内でフィールドにdefaultの値を手動代入する必要がある

stored <真偽値/メソッド>:シリアライズ時にプロパティを保存するか制御

  • stored True:デフォルト、シリアライズ時にファイルへ出力
  • stored False:このプロパティを永久に保存しない
  • stored IsNeedSave:真偽値メソッドを呼び出し動的に保存可否を判定

シリアライズ例

type
  TWebPage = class
  private
    FColor: TColor;
    function SetColor(const Value: TColor): TColor;
  published
    // default clBlackはデフォルト黒色、コンストラクタで手動 FColor := clBlack が必要
    property Color: TColor read FColor write SetColor default clBlack;
    // stored False の場合 lfm/json に保存されない
    property TempCache: string read FTemp write FTemp stored False;
  end;

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です