カスタム属性をつけたフィールドの値を取得するサンプルを作り、カスタム属性の使い方を試してみます。
まず、次のようなカスタム属性を作成します。
type
LogAttribute = class(TCustomAttribute)
end;
このLogAttributeをつけたフィールドだけを出力するプログラムを作成します。
type
TSample = class
private
[Log]
FVal1: string;
[Log]
FVal2: string;
FVal3: string;
public
constructor Create(const AVal1, AVal2, AVal3: string);
end;
constructor TSample.Create(const AVal1, AVal2, AVal3: string);
begin
FVal1 := AVal1;
FVal2 := AVal2;
FVal3 := AVal3;
end;
FVal1とFVal2に属性をつけました。
FVal3には属性はつけていません。
var
Sample: TSample;
begin
Sample := TSample.Create('aa', 'bbb', 'cccc');
PrintLogAttr(Sample);
Sample.Free;
end.
このコードを実行すると、PrintLogAttr関数でLogAttributeの属性がついているフィールドの値を出力します。
PrintLogAttr関数の実装は次のようになります。
RTTIを使用してオブジェクトの情報を取得します。
フィールドにつけた属性はTRttiFieldのGetAttributesメソッドで取得できます。
procedure PrintLogAttr(const Arg: TSample);
var
LContext: TRttiContext;
LType: TRttiType;
LField: TRttiField;
LAttr: TCustomAttribute;
LFieldValue: string;
begin
LContext := TRttiContext.Create;
LType := LContext.GetType(TSample);
// すべてのフィールドを取得する
for LField in LType.GetFields do
begin
// フィールドの属性を取得する
for LAttr in LField.GetAttributes do
begin
// 属性がLogAttributeであるか調べる
if LAttr is LogAttribute then
begin
// 属性がLogAttributeのときはフィールドの値を取得する
LFieldValue := LField.GetValue(Arg).AsString;
// フィールドの値を出力する
WriteLn(LField.Name + '=' + LFieldValue);
end;
end;
end;
end;
実行結果は次のようになります。
FVal1=aa
FVal2=bbb