Get the attribute value of a specific property

I have a class with published properties that I serialize in 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; 

Since the size of the XML is critical, I use attributes to provide a shorter name for the property (that is, I cannot define a property with the name "Class"). Serialization is as follows:

 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; 

I need a condition like: if the property marked with MyAttr, get "MyAttr.Name" instead of "lPropInfo ^ .Name".

+7
source share
1 answer

You can use this function to get the name of your attribute from this property (you wrote it in a minute, it may take some optimization):

 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; 

Name it as follows:

 sAttrName:= GetPropAttribValue(obj.ClassInfo, lPropName); 

So, if this function returns an empty string, it means that the property is not marked MyAttr, and then you need to use "lPropInfo ^ .Name".

+5
source

All Articles