7
XMLにシリアライズした公開された小道具を持つクラスがあります。特定のプロパティの属性値を取得する
MyAttr = class(TCustomAttribute)
private
FName: string;
public
constructor Create(const Name: string);
property Name: string read FName write FName;
end;
MyClass = class(TPersistent)
private
FClassCaption: string;
published
[MyAttr('Class')]
property ClassCaption: string read FClassCaption write FClassCaption;
end;
XMLサイズが重要なので、属性を使用してプロパティの名前を短縮します(つまり、「クラス」という名前のプロパティを定義できません)。 シリアライゼーションは、次のように実装:
lPropCount := GetPropList(PTypeInfo(Obj.ClassInfo), lPropList);
for i := 0 to lPropCount - 1 do begin
lPropInfo := lPropList^[i];
lPropName := string(lPropInfo^.Name);
if IsPublishedProp(Obj, lPropName) then begin
ItemNode := RootNode.AddChild(lPropName);
ItemNode.NodeValue := VarToStr(GetPropValue(Obj, lPropName, False));
end;
end;
のように私は条件を必要とする:プロパティはMyAttrでマークされた場合は、 "lPropInfo^.nameの" の代わりに "MyAttr.Name" を取得します。
uses
SysUtils,
Rtti,
TypInfo;
function GetPropAttribValue(ATypeInfo: Pointer; const PropName: string): string;
var
ctx: TRttiContext;
typ: TRttiType;
Aprop: TRttiProperty;
attr: TCustomAttribute;
begin
Result := '';
ctx := TRttiContext.Create;
typ := ctx.GetType(ATypeInfo);
for Aprop in typ.GetProperties do
begin
if (Aprop.Visibility = mvPublished) and (SameText(PropName, Aprop.Name)) then
begin
for attr in AProp.GetAttributes do
begin
if attr is MyAttr then
begin
Result := MyAttr(attr).Name;
Exit;
end;
end;
Break;
end;
end;
end;
このようにそれを呼び出します:
sAttrName:= GetPropAttribValue(obj.ClassInfo, lPropName);