Получить значение атрибута конкретного свойства - PullRequest
7 голосов
/ 23 ноября 2011

У меня есть класс с опубликованными реквизитами, которые я сериализую в 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».

1 Ответ

5 голосов
/ 23 ноября 2011

Вы можете использовать эту функцию, чтобы получить имя вашего атрибута из заданного свойства (записали его через минуту, возможно, потребуется некоторая оптимизация):

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);

Так что, если эта функция возвращает пустую строку, это означает, что свойство не помечено MyAttr, и тогда вам нужно использовать «lPropInfo ^ .Name».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...